Merge branch 'master' into merge-vsphere-builder
This commit is contained in:
commit
8cb1f7b1c1
82
CHANGELOG.md
82
CHANGELOG.md
|
@ -1,49 +1,115 @@
|
|||
## 1.5.0 (Upcoming)
|
||||
## 1.5.2 (Upcoming)
|
||||
|
||||
### IMPROVEMENTS:
|
||||
* builder/amazon: Add source AMI owner ID/name to template engines [GH-8550]
|
||||
* builder/azure: Set expiry for image versions in SIG [GH-8561]
|
||||
* core: clean up messy log line in plugin execution. [GH-8542]
|
||||
|
||||
### Bug Fixes:
|
||||
* builder/virtualbox-ovf: Remove config dependency from StepImport [GH-8509]
|
||||
* builder/virtualbox-vm: use config as a non pointer to avoid a panic [GH-8576]
|
||||
* core: Fix crash when build.sources is set to an invalid name [GH-8569]
|
||||
* core: Fix loading of external plugins. GH-8543]
|
||||
* post-processor/vagrant: correctly handle the diskSize property as a qemu size
|
||||
string [GH-8567]
|
||||
* provisioner/ansible: Fix password sanitization to account for empty string
|
||||
values. [GH-8570]
|
||||
|
||||
## 1.5.1 (December 20, 2019)
|
||||
This was a fast-follow release to fix a number of panics that we introduced when
|
||||
making changes for HCL2.
|
||||
|
||||
### IMPROVEMENTS:
|
||||
* builder/alicloud: Add show_expired option for describing images [GH-8425]
|
||||
|
||||
### Bug Fixes:
|
||||
* builder/cloudstack: Fix panics associated with loading config [GH-8513]
|
||||
* builder/hyperv/iso: Fix panics associated with loading config [GH-8513]
|
||||
* builder/hyperv/vmcx: Fix panics associated with loading config [GH-8513]
|
||||
* builder/jdcloud: Update jdcloud statebag to use pointers for config [GH-8518]
|
||||
* builder/linode: Fix panics associated with loading config [GH-8513]
|
||||
* builder/lxc: Fix panics associated with loading config [GH-8513]
|
||||
* builder/lxd: Fix panics associated with loading config [GH-8513]
|
||||
* builder/oneandone: Fix panics associated with loading config [GH-8513]
|
||||
* builder/oracle/classic: Fix panics associated with loading config [GH-8513]
|
||||
* builder/oracle/oci: Fix panics associated with loading config [GH-8513]
|
||||
* builder/osc/bsuvolume: Fix panics associated with loading config [GH-8513]
|
||||
* builder/parallels/pvm: Fix panics associated with loading config [GH-8513]
|
||||
* builder/profitbricks: Fix panics associated with loading config [GH-8513]
|
||||
* builder/scaleway: Fix panics associated with loading config [GH-8513]
|
||||
* builder/vagrant: Fix panics associated with loading config [GH-8513]
|
||||
* builder/virtualbox/ovf: Fix panics associated with loading config [GH-8513]
|
||||
* builder/virtualbox: Configure NAT interface before forwarded port mapping
|
||||
#8514
|
||||
* post-processor/vagrant-cloud: Configure NAT interface before forwarded port
|
||||
mapping [GH-8514]
|
||||
|
||||
## 1.5.0 (December 18, 2019)
|
||||
|
||||
### IMPROVEMENTS:
|
||||
* builder/amazon: Add no_ephemeral template option to remove ephemeral drives
|
||||
from launch mappings. [GH-8393]
|
||||
* builder/amazon: Add validation for `subnet_id` when specifying `vpc_id`
|
||||
* builder/amazon: Add validation for "subnet_id" when specifying "vpc_id"
|
||||
[GH-8360] [GH-8387] [GH-8391]
|
||||
* builder/amazon: allow enabling ena/sr-iov on ebssurrogate spot instances
|
||||
[GH-8397]
|
||||
* builder/amazon: Retry runinstances aws api call to mitigate throttling
|
||||
[GH-8342]
|
||||
* builder/hyperone: Update builder schema and tags [GH-8444]
|
||||
* builder/qemu: Add display template option for qemu. [GH-7676]
|
||||
* builder/qemu: Disk Size is now read as a string to support units. [GH-8320]
|
||||
[GH-7546]
|
||||
* builder/qemu: Add fixer to convert disk size from int to string [GH-8390]
|
||||
* builder/qemu: Disk Size is now read as a string to support units. [GH-8320]
|
||||
[GH-7546]
|
||||
* builder/qemu: When a user adds a new drive in qemuargs, process it to make
|
||||
sure that necessary settings are applied to that drive. [GH-8380]
|
||||
* builder/vmware: Fix error message when ovftool is missing [GH-8371]
|
||||
* core: Cleanup logging for external plugins [GH-8471]
|
||||
* core: HCL2 template support is now in beta. [GH-8423]
|
||||
* core: Interpolation within provisioners can now access build-specific values
|
||||
like Host IP, communicator password, and more. [GH-7866]
|
||||
* core: Various fixes to error handling. [GH-8343] [GH-8333] [GH-8316]
|
||||
[GH-8354] [GH-8361] [GH-8363] [GH-8370]
|
||||
* post-processor/docker-tag: Add support for multiple tags. [GH-8392]
|
||||
* post-processor/shell-local: Add "valid_exit_codes" option to shell-local.
|
||||
[GH-8401]
|
||||
* provisioner/chef-client: Add version selection option. [GH-8468]
|
||||
* provisioner/shell-local: Add "valid_exit_codes" option to shell-local.
|
||||
[GH-8401]
|
||||
* provisioner/shell: Add support for the `env_var_format` parameter [GH-8319]
|
||||
* provisioner/shell: Add support for the "env_var_format" parameter [GH-8319]
|
||||
|
||||
### BUG FIXES:
|
||||
* builder/amazon: Fix request retry mechanism to launch aws instance [GH-8430]
|
||||
* builder/azure: Fix PollDuration option which was overriden in some clients.
|
||||
[GH-8490]
|
||||
* builder/hyperv: Fix bug in checking VM name that could cause flakiness if
|
||||
many VMs are defined. [GH-8357]
|
||||
* builder/vagrant: Use absolute path for Vagrantfile [GH-8321]
|
||||
* builder/virtualbox: Fix panic in snapshot builder. [GH-8336] [GH-8329]
|
||||
* communicator/winrm: Resolve ntlm nil pointer bug by bumping go-ntlmssp
|
||||
dependency [GH-8369]
|
||||
* communicator: Fix proxy connection settings to use `SSHProxyUsername` and
|
||||
`SSHProxyPassword` where relevant instead of bastion username and password.
|
||||
* communicator: Fix proxy connection settings to use "SSHProxyUsername" and
|
||||
"SSHProxyPassword" where relevant instead of bastion username and password.
|
||||
[GH-8375]
|
||||
* core: Fix bug where Packer froze if asked to log an extremely long line
|
||||
[GH-8356]
|
||||
* core: Fix iso_target_path option; don't cache when target path is non-nil
|
||||
[GH-8394]
|
||||
* core: Return exit code 1 when builder type is not found [GH-8474]
|
||||
* core: Return exit code 1 when builder type is not found [GH-8475]
|
||||
* core: Update to newest version of go-tty to re-enable CTRL-S and CTRL-Q usage
|
||||
[GH-8364]
|
||||
|
||||
|
||||
### BACKWARDS INCOMPATIBILITIES:
|
||||
* builder/amazon: Complete deprecation of clean_ami_name template func
|
||||
[GH-8320] [GH-8193]
|
||||
* builder/qemu: Disk Size is now read as a string to support units. [GH-8320]
|
||||
[GH-7546]
|
||||
* core: Changes have been made to both the Prepare() method signature on the
|
||||
builder interface and on the Provision() method signature on the
|
||||
provisioner interface. [GH-7866]
|
||||
* provisioner/ansible-local: The "galaxycommand" option has been renamed to
|
||||
"galaxy_command". A fixer has been written for this, which can be invoked
|
||||
with `packer fix`. [GH-8411]
|
||||
|
||||
## 1.4.5 (November 4, 2019)
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
# builders
|
||||
|
||||
/builder/alicloud/ @chhaj5236
|
||||
/website/source/docs/builders/alicloud* @chhaj5236
|
||||
/builder/alicloud/ @chhaj5236 @alexyueer
|
||||
/website/source/docs/builders/alicloud* @chhaj5236 @alexyueer
|
||||
|
||||
/builder/azure/ @paulmey
|
||||
/website/source/docs/builders/azure* @paulmey
|
||||
|
|
|
@ -3,29 +3,42 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
"github.com/hashicorp/packer/version"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
// Config of alicloud
|
||||
type AlicloudAccessConfig struct {
|
||||
// This is the Alicloud access key. It must be provided, but it can also be
|
||||
// This is the Alicloud access key. It must be provided when profile not exist, but it can also be
|
||||
// sourced from the ALICLOUD_ACCESS_KEY environment variable.
|
||||
AlicloudAccessKey string `mapstructure:"access_key" required:"true"`
|
||||
// This is the Alicloud secret key. It must be provided, but it can also be
|
||||
AlicloudAccessKey string `mapstructure:"access_key" required:"false"`
|
||||
// This is the Alicloud secret key. It must be provided when profile not exist, but it can also be
|
||||
// sourced from the ALICLOUD_SECRET_KEY environment variable.
|
||||
AlicloudSecretKey string `mapstructure:"secret_key" required:"true"`
|
||||
// This is the Alicloud region. It must be provided, but it can also be
|
||||
AlicloudSecretKey string `mapstructure:"secret_key" required:"false"`
|
||||
// This is the Alicloud region. It must be provided when profile not exist, but it can also be
|
||||
// sourced from the ALICLOUD_REGION environment variables.
|
||||
AlicloudRegion string `mapstructure:"region" required:"true"`
|
||||
AlicloudRegion string `mapstructure:"region" required:"false"`
|
||||
// The region validation can be skipped if this value is true, the default
|
||||
// value is false.
|
||||
AlicloudSkipValidation bool `mapstructure:"skip_region_validation" required:"false"`
|
||||
// The image validation can be skipped if this value is true, the default
|
||||
// value is false.
|
||||
AlicloudSkipImageValidation bool `mapstructure:"skip_image_validation" required:"false"`
|
||||
// This is th Alicloud profile. If access_key not exist, is must be provided, but it can also be
|
||||
// sourced from the ALICLOUD_PROFILE environment variables.
|
||||
AlicloudProfile string `mapstructure:"profile" required:"false"`
|
||||
// This is the Alicloud shared credentials file path. If this file path exist, os will read access key
|
||||
// and secret key from this file.
|
||||
AlicloudSharedCredentialsFile string `mapstructure:"shared_credentials_file" required:"false"`
|
||||
// STS access token, can be set through template or by exporting as
|
||||
// environment variable such as `export SECURITY_TOKEN=value`.
|
||||
SecurityToken string `mapstructure:"security_token" required:"false"`
|
||||
|
@ -45,8 +58,22 @@ func (c *AlicloudAccessConfig) Client() (*ClientWrapper, error) {
|
|||
c.SecurityToken = os.Getenv("SECURITY_TOKEN")
|
||||
}
|
||||
|
||||
client, err := ecs.NewClientWithStsToken(c.AlicloudRegion, c.AlicloudAccessKey,
|
||||
c.AlicloudSecretKey, c.SecurityToken)
|
||||
var getProviderConfig = func(str string, key string) string {
|
||||
value, err := getConfigFromProfile(c, key)
|
||||
if err == nil && value != nil {
|
||||
str = value.(string)
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
if c.AlicloudAccessKey == "" || c.AlicloudSecretKey == "" {
|
||||
c.AlicloudAccessKey = getProviderConfig(c.AlicloudAccessKey, "access_key_id")
|
||||
c.AlicloudSecretKey = getProviderConfig(c.AlicloudSecretKey, "access_key_secret")
|
||||
c.AlicloudRegion = getProviderConfig(c.AlicloudRegion, "region_id")
|
||||
c.SecurityToken = getProviderConfig(c.SecurityToken, "sts_token")
|
||||
}
|
||||
|
||||
client, err := ecs.NewClientWithStsToken(c.AlicloudRegion, c.AlicloudAccessKey, c.AlicloudSecretKey, c.SecurityToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -86,7 +113,13 @@ func (c *AlicloudAccessConfig) Config() error {
|
|||
if c.AlicloudSecretKey == "" {
|
||||
c.AlicloudSecretKey = os.Getenv("ALICLOUD_SECRET_KEY")
|
||||
}
|
||||
if c.AlicloudAccessKey == "" || c.AlicloudSecretKey == "" {
|
||||
if c.AlicloudProfile == "" {
|
||||
c.AlicloudProfile = os.Getenv("ALICLOUD_PROFILE")
|
||||
}
|
||||
if c.AlicloudSharedCredentialsFile == "" {
|
||||
c.AlicloudSharedCredentialsFile = os.Getenv("ALICLOUD_SHARED_CREDENTIALS_FILE")
|
||||
}
|
||||
if (c.AlicloudAccessKey == "" || c.AlicloudSecretKey == "") && c.AlicloudProfile == "" {
|
||||
return fmt.Errorf("ALICLOUD_ACCESS_KEY and ALICLOUD_SECRET_KEY must be set in template file or environment variables.")
|
||||
}
|
||||
return nil
|
||||
|
@ -128,3 +161,66 @@ func (c *AlicloudAccessConfig) getSupportedRegions() ([]string, error) {
|
|||
|
||||
return validRegions, nil
|
||||
}
|
||||
|
||||
func getConfigFromProfile(c *AlicloudAccessConfig, ProfileKey string) (interface{}, error) {
|
||||
providerConfig := make(map[string]interface{})
|
||||
current := c.AlicloudProfile
|
||||
if current != "" {
|
||||
profilePath, err := homedir.Expand(c.AlicloudSharedCredentialsFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if profilePath == "" {
|
||||
profilePath = fmt.Sprintf("%s/.aliyun/config.json", os.Getenv("HOME"))
|
||||
if runtime.GOOS == "windows" {
|
||||
profilePath = fmt.Sprintf("%s/.aliyun/config.json", os.Getenv("USERPROFILE"))
|
||||
}
|
||||
}
|
||||
_, err = os.Stat(profilePath)
|
||||
if !os.IsNotExist(err) {
|
||||
data, err := ioutil.ReadFile(profilePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config := map[string]interface{}{}
|
||||
err = json.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range config["profiles"].([]interface{}) {
|
||||
if current == v.(map[string]interface{})["name"] {
|
||||
providerConfig = v.(map[string]interface{})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mode := ""
|
||||
if v, ok := providerConfig["mode"]; ok {
|
||||
mode = v.(string)
|
||||
} else {
|
||||
return v, nil
|
||||
}
|
||||
switch ProfileKey {
|
||||
case "access_key_id", "access_key_secret":
|
||||
if mode == "EcsRamRole" {
|
||||
return "", nil
|
||||
}
|
||||
case "ram_role_name":
|
||||
if mode != "EcsRamRole" {
|
||||
return "", nil
|
||||
}
|
||||
case "sts_token":
|
||||
if mode != "StsToken" {
|
||||
return "", nil
|
||||
}
|
||||
case "ram_role_arn", "ram_session_name":
|
||||
if mode != "RamRoleArn" {
|
||||
return "", nil
|
||||
}
|
||||
case "expired_seconds":
|
||||
if mode != "RamRoleArn" {
|
||||
return float64(0), nil
|
||||
}
|
||||
}
|
||||
return providerConfig[ProfileKey], nil
|
||||
}
|
||||
|
|
|
@ -32,5 +32,21 @@ func TestAlicloudAccessConfigPrepareRegion(t *testing.T) {
|
|||
t.Fatalf("shouldn't have err: %s", err)
|
||||
}
|
||||
|
||||
c.AlicloudAccessKey = ""
|
||||
if err := c.Prepare(nil); err == nil {
|
||||
t.Fatalf("should have err")
|
||||
}
|
||||
|
||||
c.AlicloudProfile = "default"
|
||||
if err := c.Prepare(nil); err != nil {
|
||||
t.Fatalf("shouldn't have err: %s", err)
|
||||
}
|
||||
|
||||
c.AlicloudProfile = ""
|
||||
os.Setenv("ALICLOUD_PROFILE", "default")
|
||||
if err := c.Prepare(nil); err != nil {
|
||||
t.Fatalf("shouldn't have err: %s", err)
|
||||
}
|
||||
|
||||
c.AlicloudSkipValidation = false
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/config"
|
||||
|
@ -41,7 +42,9 @@ const (
|
|||
ALICLOUD_DEFAULT_LONG_TIMEOUT = 3600
|
||||
)
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
err := config.Decode(&b.config, &config.DecodeOpts{
|
||||
Interpolate: true,
|
||||
InterpolateContext: &b.config.ctx,
|
||||
|
@ -53,7 +56,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
}, raws...)
|
||||
b.config.ctx.EnableEnv = true
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if b.config.PackerConfig.PackerForce {
|
||||
|
@ -68,11 +71,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...)
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, errs
|
||||
return nil, nil, errs
|
||||
}
|
||||
|
||||
packer.LogSecretFilter.Set(b.config.AlicloudAccessKey, b.config.AlicloudSecretKey)
|
||||
return nil, nil
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||
|
|
|
@ -22,10 +22,13 @@ type FlatAlicloudDiskDevice struct {
|
|||
// FlatMapstructure returns a new FlatAlicloudDiskDevice.
|
||||
// FlatAlicloudDiskDevice is an auto-generated flat version of AlicloudDiskDevice.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*AlicloudDiskDevice) FlatMapstructure() interface{} { return new(FlatAlicloudDiskDevice) }
|
||||
func (*AlicloudDiskDevice) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatAlicloudDiskDevice)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatAlicloudDiskDevice.
|
||||
// This spec is used by HCL to read the fields of FlatAlicloudDiskDevice.
|
||||
// HCL2Spec returns the hcl spec of a AlicloudDiskDevice.
|
||||
// This spec is used by HCL to read the fields of AlicloudDiskDevice.
|
||||
// The decoded values from this spec will then be applied to a FlatAlicloudDiskDevice.
|
||||
func (*FlatAlicloudDiskDevice) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"disk_name": &hcldec.AttrSpec{Name: "disk_name", Type: cty.String, Required: false},
|
||||
|
@ -50,10 +53,13 @@ type FlatConfig struct {
|
|||
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
|
||||
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
|
||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
|
||||
AlicloudAccessKey *string `mapstructure:"access_key" required:"true" cty:"access_key"`
|
||||
AlicloudSecretKey *string `mapstructure:"secret_key" required:"true" cty:"secret_key"`
|
||||
AlicloudRegion *string `mapstructure:"region" required:"true" cty:"region"`
|
||||
AlicloudAccessKey *string `mapstructure:"access_key" required:"false" cty:"access_key"`
|
||||
AlicloudSecretKey *string `mapstructure:"secret_key" required:"false" cty:"secret_key"`
|
||||
AlicloudRegion *string `mapstructure:"region" required:"false" cty:"region"`
|
||||
AlicloudSkipValidation *bool `mapstructure:"skip_region_validation" required:"false" cty:"skip_region_validation"`
|
||||
AlicloudSkipImageValidation *bool `mapstructure:"skip_image_validation" required:"false" cty:"skip_image_validation"`
|
||||
AlicloudProfile *string `mapstructure:"profile" required:"false" cty:"profile"`
|
||||
AlicloudSharedCredentialsFile *string `mapstructure:"shared_credentials_file" required:"false" cty:"shared_credentials_file"`
|
||||
SecurityToken *string `mapstructure:"security_token" required:"false" cty:"security_token"`
|
||||
AlicloudImageName *string `mapstructure:"image_name" required:"true" cty:"image_name"`
|
||||
AlicloudImageVersion *string `mapstructure:"image_version" required:"false" cty:"image_version"`
|
||||
|
@ -121,8 +127,8 @@ type FlatConfig struct {
|
|||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `cty:"ssh_private_key"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
|
@ -137,10 +143,13 @@ type FlatConfig struct {
|
|||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{} { return new(FlatConfig) }
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatConfig.
|
||||
// This spec is used by HCL to read the fields of FlatConfig.
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
|
@ -154,6 +163,9 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"secret_key": &hcldec.AttrSpec{Name: "secret_key", Type: cty.String, Required: false},
|
||||
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
|
||||
"skip_region_validation": &hcldec.AttrSpec{Name: "skip_region_validation", Type: cty.Bool, Required: false},
|
||||
"skip_image_validation": &hcldec.AttrSpec{Name: "skip_image_validation", Type: cty.Bool, Required: false},
|
||||
"profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false},
|
||||
"shared_credentials_file": &hcldec.AttrSpec{Name: "shared_credentials_file", Type: cty.String, Required: false},
|
||||
"security_token": &hcldec.AttrSpec{Name: "security_token", Type: cty.String, Required: false},
|
||||
"image_name": &hcldec.AttrSpec{Name: "image_name", Type: cty.String, Required: false},
|
||||
"image_version": &hcldec.AttrSpec{Name: "image_version", Type: cty.String, Required: false},
|
||||
|
@ -169,7 +181,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"image_ignore_data_disks": &hcldec.AttrSpec{Name: "image_ignore_data_disks", Type: cty.Bool, Required: false},
|
||||
"tags": &hcldec.BlockAttrsSpec{TypeName: "tags", ElementType: cty.String, Required: false},
|
||||
"system_disk_mapping": &hcldec.BlockSpec{TypeName: "system_disk_mapping", Nested: hcldec.ObjectSpec((*FlatAlicloudDiskDevice)(nil).HCL2Spec())},
|
||||
"image_disk_mappings": &hcldec.BlockListSpec{TypeName: "image_disk_mappings", Nested: &hcldec.BlockSpec{TypeName: "image_disk_mappings", Nested: hcldec.ObjectSpec((*FlatAlicloudDiskDevice)(nil).HCL2Spec())}},
|
||||
"image_disk_mappings": &hcldec.BlockListSpec{TypeName: "image_disk_mappings", Nested: hcldec.ObjectSpec((*FlatAlicloudDiskDevice)(nil).HCL2Spec())},
|
||||
"associate_public_ip_address": &hcldec.AttrSpec{Name: "associate_public_ip_address", Type: cty.Bool, Required: false},
|
||||
"zone_id": &hcldec.AttrSpec{Name: "zone_id", Type: cty.String, Required: false},
|
||||
"io_optimized": &hcldec.AttrSpec{Name: "io_optimized", Type: cty.Bool, Required: false},
|
||||
|
|
|
@ -35,7 +35,7 @@ func TestBuilder_Prepare_BadType(t *testing.T) {
|
|||
"access_key": []string{},
|
||||
}
|
||||
|
||||
warnings, err := b.Prepare(c)
|
||||
_, warnings, err := b.Prepare(c)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ func TestBuilderPrepare_ECSImageName(t *testing.T) {
|
|||
|
||||
// Test good
|
||||
config["image_name"] = "ecs.n1.tiny"
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func TestBuilderPrepare_ECSImageName(t *testing.T) {
|
|||
// Test bad
|
||||
config["ecs_image_name"] = "foo {{"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ func TestBuilderPrepare_ECSImageName(t *testing.T) {
|
|||
// Test bad
|
||||
delete(config, "image_name")
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
|||
|
||||
// Add a random key
|
||||
config["i_should_not_be_valid"] = true
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ func TestBuilderPrepare_Devices(t *testing.T) {
|
|||
"disk_device": "/dev/xvdc",
|
||||
},
|
||||
}
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ func TestBuilderPrepare_IgnoreDataDisks(t *testing.T) {
|
|||
var b Builder
|
||||
config := testBuilderConfig()
|
||||
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ func TestBuilderPrepare_IgnoreDataDisks(t *testing.T) {
|
|||
}
|
||||
|
||||
config["image_ignore_data_disks"] = "false"
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ func TestBuilderPrepare_IgnoreDataDisks(t *testing.T) {
|
|||
}
|
||||
|
||||
config["image_ignore_data_disks"] = "true"
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ func TestBuilderPrepare_WaitSnapshotReadyTimeout(t *testing.T) {
|
|||
var b Builder
|
||||
config := testBuilderConfig()
|
||||
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ func TestBuilderPrepare_WaitSnapshotReadyTimeout(t *testing.T) {
|
|||
}
|
||||
|
||||
config["wait_snapshot_ready_timeout"] = ALICLOUD_DEFAULT_TIMEOUT
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
|
|
@ -33,14 +33,11 @@ func TestWaitForExpectedExceedRetryTimes(t *testing.T) {
|
|||
waitDone <- true
|
||||
}()
|
||||
|
||||
timeTolerance := 1 * time.Second
|
||||
select {
|
||||
case <-waitDone:
|
||||
if iter != defaultRetryTimes {
|
||||
t.Fatalf("WaitForExpected should terminate at the %d iterations", defaultRetryTimes)
|
||||
}
|
||||
case <-time.After(defaultRetryTimes*defaultRetryInterval + timeTolerance):
|
||||
t.Fatalf("WaitForExpected should terminate within %f seconds", (defaultRetryTimes*defaultRetryInterval + timeTolerance).Seconds())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@ func (s *stepCheckAlicloudSourceImage) Run(ctx context.Context, state multistep.
|
|||
describeImagesRequest := ecs.CreateDescribeImagesRequest()
|
||||
describeImagesRequest.RegionId = config.AlicloudRegion
|
||||
describeImagesRequest.ImageId = config.AlicloudSourceImage
|
||||
if config.AlicloudSkipImageValidation {
|
||||
describeImagesRequest.ShowExpired = "true"
|
||||
}
|
||||
imagesResponse, err := client.DescribeImages(describeImagesRequest)
|
||||
if err != nil {
|
||||
return halt(state, err, "Error querying alicloud image")
|
||||
|
|
|
@ -36,7 +36,7 @@ func (s *stepConfigAlicloudSecurityGroup) Run(ctx context.Context, state multist
|
|||
if len(s.SecurityGroupId) != 0 {
|
||||
describeSecurityGroupsRequest := ecs.CreateDescribeSecurityGroupsRequest()
|
||||
describeSecurityGroupsRequest.RegionId = s.RegionId
|
||||
|
||||
describeSecurityGroupsRequest.SecurityGroupId = s.SecurityGroupId
|
||||
if networkType == InstanceNetworkVpc {
|
||||
vpcId := state.Get("vpcid").(string)
|
||||
describeSecurityGroupsRequest.VpcId = vpcId
|
||||
|
|
|
@ -77,6 +77,9 @@ func (s *stepCreateAlicloudInstance) Run(ctx context.Context, state multistep.St
|
|||
ui.Message(fmt.Sprintf("Created instance: %s", instanceId))
|
||||
s.instance = &instances.Instances.Instance[0]
|
||||
state.Put("instance", s.instance)
|
||||
// instance_id is the generic term used so that users can have access to the
|
||||
// instance id inside of the provisioners, used in step_provision.
|
||||
state.Put("instance_id", instanceId)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ package ecs
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
|
||||
"time"
|
||||
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"runtime"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
awscommon "github.com/hashicorp/packer/builder/amazon/common"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/common/chroot"
|
||||
|
@ -182,7 +183,9 @@ type Builder struct {
|
|||
runner multistep.Runner
|
||||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
b.config.ctx.Funcs = awscommon.TemplateFuncs
|
||||
err := config.Decode(&b.config, &config.DecodeOpts{
|
||||
Interpolate: true,
|
||||
|
@ -201,7 +204,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if b.config.Architecture == "" {
|
||||
|
@ -319,11 +322,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return warns, errs
|
||||
return nil, warns, errs
|
||||
}
|
||||
|
||||
packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token)
|
||||
return warns, nil
|
||||
return nil, warns, nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||
|
|
|
@ -72,10 +72,13 @@ type FlatConfig struct {
|
|||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{} { return new(FlatConfig) }
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatConfig.
|
||||
// This spec is used by HCL to read the fields of FlatConfig.
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
|
@ -93,7 +96,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"ami_product_codes": &hcldec.AttrSpec{Name: "ami_product_codes", Type: cty.List(cty.String), Required: false},
|
||||
"ami_regions": &hcldec.AttrSpec{Name: "ami_regions", Type: cty.List(cty.String), Required: false},
|
||||
"skip_region_validation": &hcldec.AttrSpec{Name: "skip_region_validation", Type: cty.Bool, Required: false},
|
||||
"tags": &hcldec.BlockAttrsSpec{TypeName: "common.TagMap", ElementType: cty.String, Required: false},
|
||||
"tags": &hcldec.BlockAttrsSpec{TypeName: "tags", ElementType: cty.String, Required: false},
|
||||
"ena_support": &hcldec.AttrSpec{Name: "ena_support", Type: cty.Bool, Required: false},
|
||||
"sriov_support": &hcldec.AttrSpec{Name: "sriov_support", Type: cty.Bool, Required: false},
|
||||
"force_deregister": &hcldec.AttrSpec{Name: "force_deregister", Type: cty.Bool, Required: false},
|
||||
|
@ -102,7 +105,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"kms_key_id": &hcldec.AttrSpec{Name: "kms_key_id", Type: cty.String, Required: false},
|
||||
"region_kms_key_ids": &hcldec.BlockAttrsSpec{TypeName: "region_kms_key_ids", ElementType: cty.String, Required: false},
|
||||
"skip_save_build_region": &hcldec.AttrSpec{Name: "skip_save_build_region", Type: cty.Bool, Required: false},
|
||||
"snapshot_tags": &hcldec.BlockAttrsSpec{TypeName: "common.TagMap", ElementType: cty.String, Required: false},
|
||||
"snapshot_tags": &hcldec.BlockAttrsSpec{TypeName: "snapshot_tags", ElementType: cty.String, Required: false},
|
||||
"snapshot_users": &hcldec.AttrSpec{Name: "snapshot_users", Type: cty.List(cty.String), Required: false},
|
||||
"snapshot_groups": &hcldec.AttrSpec{Name: "snapshot_groups", Type: cty.List(cty.String), Required: false},
|
||||
"access_key": &hcldec.AttrSpec{Name: "access_key", Type: cty.String, Required: false},
|
||||
|
@ -116,7 +119,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
|
||||
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
|
||||
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
|
||||
"ami_block_device_mappings": &hcldec.BlockListSpec{TypeName: "ami_block_device_mappings", Nested: &hcldec.BlockSpec{TypeName: "ami_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())}},
|
||||
"ami_block_device_mappings": &hcldec.BlockListSpec{TypeName: "ami_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
|
||||
"chroot_mounts": &hcldec.BlockListSpec{TypeName: "chroot_mounts", Nested: &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.String), Required: false}},
|
||||
"command_wrapper": &hcldec.AttrSpec{Name: "command_wrapper", Type: cty.String, Required: false},
|
||||
"copy_files": &hcldec.AttrSpec{Name: "copy_files", Type: cty.List(cty.String), Required: false},
|
||||
|
@ -133,7 +136,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"root_volume_type": &hcldec.AttrSpec{Name: "root_volume_type", Type: cty.String, Required: false},
|
||||
"source_ami": &hcldec.AttrSpec{Name: "source_ami", Type: cty.String, Required: false},
|
||||
"source_ami_filter": &hcldec.BlockSpec{TypeName: "source_ami_filter", Nested: hcldec.ObjectSpec((*common.FlatAmiFilterOptions)(nil).HCL2Spec())},
|
||||
"root_volume_tags": &hcldec.BlockAttrsSpec{TypeName: "common.TagMap", ElementType: cty.String, Required: false},
|
||||
"root_volume_tags": &hcldec.BlockAttrsSpec{TypeName: "root_volume_tags", ElementType: cty.String, Required: false},
|
||||
"ami_architecture": &hcldec.AttrSpec{Name: "ami_architecture", Type: cty.String, Required: false},
|
||||
}
|
||||
return s
|
||||
|
|
|
@ -31,7 +31,7 @@ func TestBuilderPrepare_AMIName(t *testing.T) {
|
|||
// Test good
|
||||
config["ami_name"] = "foo"
|
||||
config["skip_region_validation"] = true
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ func TestBuilderPrepare_AMIName(t *testing.T) {
|
|||
// Test bad
|
||||
config["ami_name"] = "foo {{"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ func TestBuilderPrepare_AMIName(t *testing.T) {
|
|||
// Test bad
|
||||
delete(config, "ami_name")
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ func TestBuilderPrepare_ChrootMounts(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
config["chroot_mounts"] = nil
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ func TestBuilderPrepare_ChrootMountsBadDefaults(t *testing.T) {
|
|||
config["chroot_mounts"] = [][]string{
|
||||
{"bad"},
|
||||
}
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ func TestBuilderPrepare_SourceAmi(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
config["source_ami"] = ""
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ func TestBuilderPrepare_SourceAmi(t *testing.T) {
|
|||
}
|
||||
|
||||
config["source_ami"] = "foo"
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ func TestBuilderPrepare_CommandWrapper(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
config["command_wrapper"] = "echo hi; {{.Command}}"
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ func TestBuilderPrepare_CopyFiles(t *testing.T) {
|
|||
b := &Builder{}
|
||||
config := testConfig()
|
||||
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ func TestBuilderPrepare_CopyFilesNoDefault(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
config["copy_files"] = []string{}
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ func TestBuilderPrepare_RootDeviceNameAndAMIMappings(t *testing.T) {
|
|||
config["root_device_name"] = "/dev/sda"
|
||||
config["ami_block_device_mappings"] = []interface{}{map[string]string{}}
|
||||
config["root_volume_size"] = 15
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) == 0 {
|
||||
t.Fatal("Missing warning, stating block device mappings will be overwritten")
|
||||
} else if len(warnings) > 1 {
|
||||
|
@ -187,7 +187,7 @@ func TestBuilderPrepare_AMIMappingsNoRootDeviceName(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
config["ami_block_device_mappings"] = []interface{}{map[string]string{}}
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ func TestBuilderPrepare_RootDeviceNameNoAMIMappings(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
config["root_device_name"] = "/dev/sda"
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
|
|
@ -18,10 +18,13 @@ type FlatVaultAWSEngineOptions struct {
|
|||
// FlatMapstructure returns a new FlatVaultAWSEngineOptions.
|
||||
// FlatVaultAWSEngineOptions is an auto-generated flat version of VaultAWSEngineOptions.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*VaultAWSEngineOptions) FlatMapstructure() interface{} { return new(FlatVaultAWSEngineOptions) }
|
||||
func (*VaultAWSEngineOptions) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatVaultAWSEngineOptions)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatVaultAWSEngineOptions.
|
||||
// This spec is used by HCL to read the fields of FlatVaultAWSEngineOptions.
|
||||
// HCL2Spec returns the hcl spec of a VaultAWSEngineOptions.
|
||||
// This spec is used by HCL to read the fields of VaultAWSEngineOptions.
|
||||
// The decoded values from this spec will then be applied to a FlatVaultAWSEngineOptions.
|
||||
func (*FlatVaultAWSEngineOptions) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"name": &hcldec.AttrSpec{Name: "name", Type: cty.String, Required: false},
|
||||
|
|
|
@ -24,10 +24,13 @@ type FlatBlockDevice struct {
|
|||
// FlatMapstructure returns a new FlatBlockDevice.
|
||||
// FlatBlockDevice is an auto-generated flat version of BlockDevice.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*BlockDevice) FlatMapstructure() interface{} { return new(FlatBlockDevice) }
|
||||
func (*BlockDevice) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatBlockDevice)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatBlockDevice.
|
||||
// This spec is used by HCL to read the fields of FlatBlockDevice.
|
||||
// HCL2Spec returns the hcl spec of a BlockDevice.
|
||||
// This spec is used by HCL to read the fields of BlockDevice.
|
||||
// The decoded values from this spec will then be applied to a FlatBlockDevice.
|
||||
func (*FlatBlockDevice) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"delete_on_termination": &hcldec.AttrSpec{Name: "delete_on_termination", Type: cty.Bool, Required: false},
|
||||
|
|
|
@ -7,10 +7,12 @@ import (
|
|||
)
|
||||
|
||||
type BuildInfoTemplate struct {
|
||||
BuildRegion string
|
||||
SourceAMI string
|
||||
SourceAMIName string
|
||||
SourceAMITags map[string]string
|
||||
BuildRegion string
|
||||
SourceAMI string
|
||||
SourceAMIName string
|
||||
SourceAMIOwner string
|
||||
SourceAMIOwnerName string
|
||||
SourceAMITags map[string]string
|
||||
}
|
||||
|
||||
func extractBuildInfo(region string, state multistep.StateBag) *BuildInfoTemplate {
|
||||
|
@ -28,9 +30,11 @@ func extractBuildInfo(region string, state multistep.StateBag) *BuildInfoTemplat
|
|||
}
|
||||
|
||||
return &BuildInfoTemplate{
|
||||
BuildRegion: region,
|
||||
SourceAMI: aws.StringValue(sourceAMI.ImageId),
|
||||
SourceAMIName: aws.StringValue(sourceAMI.Name),
|
||||
SourceAMITags: sourceAMITags,
|
||||
BuildRegion: region,
|
||||
SourceAMI: aws.StringValue(sourceAMI.ImageId),
|
||||
SourceAMIName: aws.StringValue(sourceAMI.Name),
|
||||
SourceAMIOwner: aws.StringValue(sourceAMI.OwnerId),
|
||||
SourceAMIOwnerName: aws.StringValue(sourceAMI.ImageOwnerAlias),
|
||||
SourceAMITags: sourceAMITags,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,10 @@ import (
|
|||
|
||||
func testImage() *ec2.Image {
|
||||
return &ec2.Image{
|
||||
ImageId: aws.String("ami-abcd1234"),
|
||||
Name: aws.String("ami_test_name"),
|
||||
ImageId: aws.String("ami-abcd1234"),
|
||||
Name: aws.String("ami_test_name"),
|
||||
OwnerId: aws.String("ami_test_owner_id"),
|
||||
ImageOwnerAlias: aws.String("ami_test_owner_alias"),
|
||||
Tags: []*ec2.Tag{
|
||||
{
|
||||
Key: aws.String("key-1"),
|
||||
|
@ -49,9 +51,11 @@ func TestInterpolateBuildInfo_extractBuildInfo_withSourceImage(t *testing.T) {
|
|||
buildInfo := extractBuildInfo("foo", state)
|
||||
|
||||
expected := BuildInfoTemplate{
|
||||
BuildRegion: "foo",
|
||||
SourceAMI: "ami-abcd1234",
|
||||
SourceAMIName: "ami_test_name",
|
||||
BuildRegion: "foo",
|
||||
SourceAMI: "ami-abcd1234",
|
||||
SourceAMIName: "ami_test_name",
|
||||
SourceAMIOwner: "ami_test_owner_id",
|
||||
SourceAMIOwnerName: "ami_test_owner_alias",
|
||||
SourceAMITags: map[string]string{
|
||||
"key-1": "value-1",
|
||||
"key-2": "value-2",
|
||||
|
|
|
@ -145,6 +145,8 @@ type RunConfig struct {
|
|||
// profile](https://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html)
|
||||
// to launch the EC2 instance with.
|
||||
IamInstanceProfile string `mapstructure:"iam_instance_profile" required:"false"`
|
||||
// Whether or not to check if the IAM instance profile exists. Defaults to false
|
||||
SkipProfileValidation bool `mapstructure:"skip_profile_validation" required:"false"`
|
||||
// Temporary IAM instance profile policy document
|
||||
// If IamInstanceProfile is specified it will be used instead. Example:
|
||||
//
|
||||
|
@ -375,8 +377,20 @@ type RunConfig struct {
|
|||
WindowsPasswordTimeout time.Duration `mapstructure:"windows_password_timeout" required:"false"`
|
||||
|
||||
// Communicator settings
|
||||
Comm communicator.Config `mapstructure:",squash"`
|
||||
SSHInterface string `mapstructure:"ssh_interface"`
|
||||
Comm communicator.Config `mapstructure:",squash"`
|
||||
|
||||
// One of `public_ip`, `private_ip`, `public_dns`, or `private_dns`. If
|
||||
// set, either the public IP address, private IP address, public DNS name
|
||||
// or private DNS name will be used as the host for SSH. The default behaviour
|
||||
// if inside a VPC is to use the public IP address if available, otherwise
|
||||
// the private IP address will be used. If not in a VPC the public DNS name
|
||||
// will be used. Also works for WinRM.
|
||||
//
|
||||
// Where Packer is configured for an outbound proxy but WinRM traffic
|
||||
// should be direct, `ssh_interface` must be set to `private_dns` and
|
||||
// `<region>.compute.internal` included in the `NO_PROXY` environment
|
||||
// variable.
|
||||
SSHInterface string `mapstructure:"ssh_interface"`
|
||||
}
|
||||
|
||||
func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
|
|
|
@ -17,10 +17,13 @@ type FlatAmiFilterOptions struct {
|
|||
// FlatMapstructure returns a new FlatAmiFilterOptions.
|
||||
// FlatAmiFilterOptions is an auto-generated flat version of AmiFilterOptions.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*AmiFilterOptions) FlatMapstructure() interface{} { return new(FlatAmiFilterOptions) }
|
||||
func (*AmiFilterOptions) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatAmiFilterOptions)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatAmiFilterOptions.
|
||||
// This spec is used by HCL to read the fields of FlatAmiFilterOptions.
|
||||
// HCL2Spec returns the hcl spec of a AmiFilterOptions.
|
||||
// This spec is used by HCL to read the fields of AmiFilterOptions.
|
||||
// The decoded values from this spec will then be applied to a FlatAmiFilterOptions.
|
||||
func (*FlatAmiFilterOptions) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"filters": &hcldec.BlockAttrsSpec{TypeName: "filters", ElementType: cty.String, Required: false},
|
||||
|
@ -40,14 +43,17 @@ type FlatPolicyDocument struct {
|
|||
// FlatMapstructure returns a new FlatPolicyDocument.
|
||||
// FlatPolicyDocument is an auto-generated flat version of PolicyDocument.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*PolicyDocument) FlatMapstructure() interface{} { return new(FlatPolicyDocument) }
|
||||
func (*PolicyDocument) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatPolicyDocument)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatPolicyDocument.
|
||||
// This spec is used by HCL to read the fields of FlatPolicyDocument.
|
||||
// HCL2Spec returns the hcl spec of a PolicyDocument.
|
||||
// This spec is used by HCL to read the fields of PolicyDocument.
|
||||
// The decoded values from this spec will then be applied to a FlatPolicyDocument.
|
||||
func (*FlatPolicyDocument) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"version": &hcldec.AttrSpec{Name: "version", Type: cty.String, Required: false},
|
||||
"statement": &hcldec.BlockListSpec{TypeName: "statement", Nested: &hcldec.BlockSpec{TypeName: "statement", Nested: hcldec.ObjectSpec((*FlatStatement)(nil).HCL2Spec())}},
|
||||
"statement": &hcldec.BlockListSpec{TypeName: "statement", Nested: hcldec.ObjectSpec((*FlatStatement)(nil).HCL2Spec())},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
@ -61,12 +67,13 @@ type FlatSecurityGroupFilterOptions struct {
|
|||
// FlatMapstructure returns a new FlatSecurityGroupFilterOptions.
|
||||
// FlatSecurityGroupFilterOptions is an auto-generated flat version of SecurityGroupFilterOptions.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*SecurityGroupFilterOptions) FlatMapstructure() interface{} {
|
||||
func (*SecurityGroupFilterOptions) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatSecurityGroupFilterOptions)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatSecurityGroupFilterOptions.
|
||||
// This spec is used by HCL to read the fields of FlatSecurityGroupFilterOptions.
|
||||
// HCL2Spec returns the hcl spec of a SecurityGroupFilterOptions.
|
||||
// This spec is used by HCL to read the fields of SecurityGroupFilterOptions.
|
||||
// The decoded values from this spec will then be applied to a FlatSecurityGroupFilterOptions.
|
||||
func (*FlatSecurityGroupFilterOptions) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"filters": &hcldec.BlockAttrsSpec{TypeName: "filters", ElementType: cty.String, Required: false},
|
||||
|
@ -85,10 +92,13 @@ type FlatStatement struct {
|
|||
// FlatMapstructure returns a new FlatStatement.
|
||||
// FlatStatement is an auto-generated flat version of Statement.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Statement) FlatMapstructure() interface{} { return new(FlatStatement) }
|
||||
func (*Statement) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatStatement)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatStatement.
|
||||
// This spec is used by HCL to read the fields of FlatStatement.
|
||||
// HCL2Spec returns the hcl spec of a Statement.
|
||||
// This spec is used by HCL to read the fields of Statement.
|
||||
// The decoded values from this spec will then be applied to a FlatStatement.
|
||||
func (*FlatStatement) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"effect": &hcldec.AttrSpec{Name: "effect", Type: cty.String, Required: false},
|
||||
|
@ -109,10 +119,13 @@ type FlatSubnetFilterOptions struct {
|
|||
// FlatMapstructure returns a new FlatSubnetFilterOptions.
|
||||
// FlatSubnetFilterOptions is an auto-generated flat version of SubnetFilterOptions.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*SubnetFilterOptions) FlatMapstructure() interface{} { return new(FlatSubnetFilterOptions) }
|
||||
func (*SubnetFilterOptions) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatSubnetFilterOptions)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatSubnetFilterOptions.
|
||||
// This spec is used by HCL to read the fields of FlatSubnetFilterOptions.
|
||||
// HCL2Spec returns the hcl spec of a SubnetFilterOptions.
|
||||
// This spec is used by HCL to read the fields of SubnetFilterOptions.
|
||||
// The decoded values from this spec will then be applied to a FlatSubnetFilterOptions.
|
||||
func (*FlatSubnetFilterOptions) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"filters": &hcldec.BlockAttrsSpec{TypeName: "filters", ElementType: cty.String, Required: false},
|
||||
|
@ -131,10 +144,13 @@ type FlatVpcFilterOptions struct {
|
|||
// FlatMapstructure returns a new FlatVpcFilterOptions.
|
||||
// FlatVpcFilterOptions is an auto-generated flat version of VpcFilterOptions.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*VpcFilterOptions) FlatMapstructure() interface{} { return new(FlatVpcFilterOptions) }
|
||||
func (*VpcFilterOptions) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatVpcFilterOptions)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatVpcFilterOptions.
|
||||
// This spec is used by HCL to read the fields of FlatVpcFilterOptions.
|
||||
// HCL2Spec returns the hcl spec of a VpcFilterOptions.
|
||||
// This spec is used by HCL to read the fields of VpcFilterOptions.
|
||||
// The decoded values from this spec will then be applied to a FlatVpcFilterOptions.
|
||||
func (*FlatVpcFilterOptions) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"filters": &hcldec.BlockAttrsSpec{TypeName: "filters", ElementType: cty.String, Required: false},
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
commonhelper "github.com/hashicorp/packer/helper/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
@ -91,16 +90,13 @@ WaitLoop:
|
|||
"Password (since debug is enabled): %s", s.Comm.WinRMPassword))
|
||||
}
|
||||
// store so that we can access this later during provisioning
|
||||
|
||||
commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword, s.BuildName)
|
||||
state.Put("winrm_password", s.Comm.WinRMPassword)
|
||||
packer.LogSecretFilter.Set(s.Comm.WinRMPassword)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *StepGetPassword) Cleanup(multistep.StateBag) {
|
||||
commonhelper.RemoveSharedStateFile("winrm_password", s.BuildName)
|
||||
}
|
||||
func (s *StepGetPassword) Cleanup(multistep.StateBag) {}
|
||||
|
||||
func (s *StepGetPassword) waitForPassword(ctx context.Context, state multistep.StateBag) (string, error) {
|
||||
ec2conn := state.Get("ec2").(*ec2.EC2)
|
||||
|
|
|
@ -2,11 +2,10 @@ package common
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"encoding/json"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/packer/common/uuid"
|
||||
|
@ -16,6 +15,7 @@ import (
|
|||
|
||||
type StepIamInstanceProfile struct {
|
||||
IamInstanceProfile string
|
||||
SkipProfileValidation bool
|
||||
TemporaryIamInstanceProfilePolicyDocument *PolicyDocument
|
||||
createdInstanceProfileName string
|
||||
createdRoleName string
|
||||
|
@ -30,16 +30,18 @@ func (s *StepIamInstanceProfile) Run(ctx context.Context, state multistep.StateB
|
|||
state.Put("iamInstanceProfile", "")
|
||||
|
||||
if len(s.IamInstanceProfile) > 0 {
|
||||
_, err := iamsvc.GetInstanceProfile(
|
||||
&iam.GetInstanceProfileInput{
|
||||
InstanceProfileName: aws.String(s.IamInstanceProfile),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Couldn't find specified instance profile: %s", err)
|
||||
log.Printf("[DEBUG] %s", err.Error())
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
if !s.SkipProfileValidation {
|
||||
_, err := iamsvc.GetInstanceProfile(
|
||||
&iam.GetInstanceProfileInput{
|
||||
InstanceProfileName: aws.String(s.IamInstanceProfile),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Couldn't find specified instance profile: %s", err)
|
||||
log.Printf("[DEBUG] %s", err.Error())
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
log.Printf("Using specified instance profile: %v", s.IamInstanceProfile)
|
||||
state.Put("iamInstanceProfile", s.IamInstanceProfile)
|
||||
|
|
|
@ -280,6 +280,9 @@ func (s *StepRunSourceInstance) Run(ctx context.Context, state multistep.StateBa
|
|||
}
|
||||
|
||||
state.Put("instance", instance)
|
||||
// instance_id is the generic term used so that users can have access to the
|
||||
// instance id inside of the provisioners, used in step_provision.
|
||||
state.Put("instance_id", instance.InstanceId)
|
||||
|
||||
// If we're in a region that doesn't support tagging on instance creation,
|
||||
// do that now.
|
||||
|
|
|
@ -441,6 +441,9 @@ func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag)
|
|||
}
|
||||
|
||||
state.Put("instance", instance)
|
||||
// instance_id is the generic term used so that users can have access to the
|
||||
// instance id inside of the provisioners, used in step_provision.
|
||||
state.Put("instance_id", instance.InstanceId)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
awscommon "github.com/hashicorp/packer/builder/amazon/common"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
|
@ -72,7 +73,9 @@ type Builder struct {
|
|||
runner multistep.Runner
|
||||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
b.config.ctx.Funcs = awscommon.TemplateFuncs
|
||||
err := config.Decode(&b.config, &config.DecodeOpts{
|
||||
Interpolate: true,
|
||||
|
@ -89,7 +92,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if b.config.PackerConfig.PackerForce {
|
||||
|
@ -123,11 +126,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return warns, errs
|
||||
return nil, warns, errs
|
||||
}
|
||||
|
||||
packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token)
|
||||
return warns, nil
|
||||
return nil, warns, nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||
|
@ -234,6 +237,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
},
|
||||
&awscommon.StepIamInstanceProfile{
|
||||
IamInstanceProfile: b.config.IamInstanceProfile,
|
||||
SkipProfileValidation: b.config.SkipProfileValidation,
|
||||
TemporaryIamInstanceProfilePolicyDocument: b.config.TemporaryIamInstanceProfilePolicyDocument,
|
||||
},
|
||||
&awscommon.StepCleanupVolumes{
|
||||
|
|
|
@ -55,6 +55,7 @@ type FlatConfig struct {
|
|||
EbsOptimized *bool `mapstructure:"ebs_optimized" required:"false" cty:"ebs_optimized"`
|
||||
EnableT2Unlimited *bool `mapstructure:"enable_t2_unlimited" required:"false" cty:"enable_t2_unlimited"`
|
||||
IamInstanceProfile *string `mapstructure:"iam_instance_profile" required:"false" cty:"iam_instance_profile"`
|
||||
SkipProfileValidation *bool `mapstructure:"skip_profile_validation" required:"false" cty:"skip_profile_validation"`
|
||||
TemporaryIamInstanceProfilePolicyDocument *common.FlatPolicyDocument `mapstructure:"temporary_iam_instance_profile_policy_document" required:"false" cty:"temporary_iam_instance_profile_policy_document"`
|
||||
InstanceInitiatedShutdownBehavior *string `mapstructure:"shutdown_behavior" required:"false" cty:"shutdown_behavior"`
|
||||
InstanceType *string `mapstructure:"instance_type" required:"true" cty:"instance_type"`
|
||||
|
@ -106,8 +107,8 @@ type FlatConfig struct {
|
|||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `cty:"ssh_private_key"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
|
@ -126,10 +127,13 @@ type FlatConfig struct {
|
|||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{} { return new(FlatConfig) }
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatConfig.
|
||||
// This spec is used by HCL to read the fields of FlatConfig.
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
|
@ -158,7 +162,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"ami_groups": &hcldec.AttrSpec{Name: "ami_groups", Type: cty.List(cty.String), Required: false},
|
||||
"ami_product_codes": &hcldec.AttrSpec{Name: "ami_product_codes", Type: cty.List(cty.String), Required: false},
|
||||
"ami_regions": &hcldec.AttrSpec{Name: "ami_regions", Type: cty.List(cty.String), Required: false},
|
||||
"tags": &hcldec.BlockAttrsSpec{TypeName: "common.TagMap", ElementType: cty.String, Required: false},
|
||||
"tags": &hcldec.BlockAttrsSpec{TypeName: "tags", ElementType: cty.String, Required: false},
|
||||
"ena_support": &hcldec.AttrSpec{Name: "ena_support", Type: cty.Bool, Required: false},
|
||||
"sriov_support": &hcldec.AttrSpec{Name: "sriov_support", Type: cty.Bool, Required: false},
|
||||
"force_deregister": &hcldec.AttrSpec{Name: "force_deregister", Type: cty.Bool, Required: false},
|
||||
|
@ -167,7 +171,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"kms_key_id": &hcldec.AttrSpec{Name: "kms_key_id", Type: cty.String, Required: false},
|
||||
"region_kms_key_ids": &hcldec.BlockAttrsSpec{TypeName: "region_kms_key_ids", ElementType: cty.String, Required: false},
|
||||
"skip_save_build_region": &hcldec.AttrSpec{Name: "skip_save_build_region", Type: cty.Bool, Required: false},
|
||||
"snapshot_tags": &hcldec.BlockAttrsSpec{TypeName: "common.TagMap", ElementType: cty.String, Required: false},
|
||||
"snapshot_tags": &hcldec.BlockAttrsSpec{TypeName: "snapshot_tags", ElementType: cty.String, Required: false},
|
||||
"snapshot_users": &hcldec.AttrSpec{Name: "snapshot_users", Type: cty.List(cty.String), Required: false},
|
||||
"snapshot_groups": &hcldec.AttrSpec{Name: "snapshot_groups", Type: cty.List(cty.String), Required: false},
|
||||
"associate_public_ip_address": &hcldec.AttrSpec{Name: "associate_public_ip_address", Type: cty.Bool, Required: false},
|
||||
|
@ -177,6 +181,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"ebs_optimized": &hcldec.AttrSpec{Name: "ebs_optimized", Type: cty.Bool, Required: false},
|
||||
"enable_t2_unlimited": &hcldec.AttrSpec{Name: "enable_t2_unlimited", Type: cty.Bool, Required: false},
|
||||
"iam_instance_profile": &hcldec.AttrSpec{Name: "iam_instance_profile", Type: cty.String, Required: false},
|
||||
"skip_profile_validation": &hcldec.AttrSpec{Name: "skip_profile_validation", Type: cty.Bool, Required: false},
|
||||
"temporary_iam_instance_profile_policy_document": &hcldec.BlockSpec{TypeName: "temporary_iam_instance_profile_policy_document", Nested: hcldec.ObjectSpec((*common.FlatPolicyDocument)(nil).HCL2Spec())},
|
||||
"shutdown_behavior": &hcldec.AttrSpec{Name: "shutdown_behavior", Type: cty.String, Required: false},
|
||||
"instance_type": &hcldec.AttrSpec{Name: "instance_type", Type: cty.String, Required: false},
|
||||
|
@ -239,9 +244,9 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
|
||||
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
|
||||
"ssh_interface": &hcldec.AttrSpec{Name: "ssh_interface", Type: cty.String, Required: false},
|
||||
"ami_block_device_mappings": &hcldec.BlockListSpec{TypeName: "ami_block_device_mappings", Nested: &hcldec.BlockSpec{TypeName: "ami_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())}},
|
||||
"launch_block_device_mappings": &hcldec.BlockListSpec{TypeName: "launch_block_device_mappings", Nested: &hcldec.BlockSpec{TypeName: "launch_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())}},
|
||||
"run_volume_tags": &hcldec.BlockAttrsSpec{TypeName: "common.TagMap", ElementType: cty.String, Required: false},
|
||||
"ami_block_device_mappings": &hcldec.BlockListSpec{TypeName: "ami_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
|
||||
"launch_block_device_mappings": &hcldec.BlockListSpec{TypeName: "launch_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
|
||||
"run_volume_tags": &hcldec.BlockAttrsSpec{TypeName: "run_volume_tags", ElementType: cty.String, Required: false},
|
||||
"no_ephemeral": &hcldec.AttrSpec{Name: "no_ephemeral", Type: cty.Bool, Required: false},
|
||||
}
|
||||
return s
|
||||
|
|
|
@ -32,7 +32,7 @@ func TestBuilder_Prepare_BadType(t *testing.T) {
|
|||
"access_key": []string{},
|
||||
}
|
||||
|
||||
warnings, err := b.Prepare(c)
|
||||
_, warnings, err := b.Prepare(c)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ func TestBuilderPrepare_AMIName(t *testing.T) {
|
|||
// Test good
|
||||
config["ami_name"] = "foo"
|
||||
config["skip_region_validation"] = true
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ func TestBuilderPrepare_AMIName(t *testing.T) {
|
|||
// Test bad
|
||||
config["ami_name"] = "foo {{"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ func TestBuilderPrepare_AMIName(t *testing.T) {
|
|||
// Test bad
|
||||
delete(config, "ami_name")
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
|||
|
||||
// Add a random key
|
||||
config["i_should_not_be_valid"] = true
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ func TestBuilderPrepare_InvalidShutdownBehavior(t *testing.T) {
|
|||
// Test good
|
||||
config["shutdown_behavior"] = "terminate"
|
||||
config["skip_region_validation"] = true
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ func TestBuilderPrepare_InvalidShutdownBehavior(t *testing.T) {
|
|||
|
||||
// Test good
|
||||
config["shutdown_behavior"] = "stop"
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ func TestBuilderPrepare_InvalidShutdownBehavior(t *testing.T) {
|
|||
|
||||
// Test bad
|
||||
config["shutdown_behavior"] = "foobar"
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//go:generate struct-markdown
|
||||
//go:generate mapstructure-to-hcl2 -type Config,RootBlockDevice,BlockDevice
|
||||
|
||||
// The ebssurrogate package contains a packer.Builder implementation that
|
||||
// builds a new EBS-backed AMI using an ephemeral instance.
|
||||
|
@ -11,6 +12,7 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
awscommon "github.com/hashicorp/packer/builder/amazon/common"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
|
@ -70,7 +72,9 @@ type Builder struct {
|
|||
runner multistep.Runner
|
||||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
b.config.ctx.Funcs = awscommon.TemplateFuncs
|
||||
err := config.Decode(&b.config, &config.DecodeOpts{
|
||||
Interpolate: true,
|
||||
|
@ -87,7 +91,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if b.config.PackerConfig.PackerForce {
|
||||
|
@ -145,12 +149,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
errs = packer.MultiErrorAppend(errs, errors.New(`The only valid ami_architecture values are "x86_64" and "arm64"`))
|
||||
}
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return warns, errs
|
||||
return nil, warns, errs
|
||||
}
|
||||
|
||||
packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token)
|
||||
|
||||
return warns, nil
|
||||
return nil, warns, nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||
|
@ -257,6 +261,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
},
|
||||
&awscommon.StepIamInstanceProfile{
|
||||
IamInstanceProfile: b.config.IamInstanceProfile,
|
||||
SkipProfileValidation: b.config.SkipProfileValidation,
|
||||
TemporaryIamInstanceProfilePolicyDocument: b.config.TemporaryIamInstanceProfilePolicyDocument,
|
||||
},
|
||||
&awscommon.StepCleanupVolumes{
|
||||
|
|
|
@ -0,0 +1,331 @@
|
|||
// Code generated by "mapstructure-to-hcl2 -type Config,RootBlockDevice,BlockDevice"; DO NOT EDIT.
|
||||
package ebssurrogate
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/builder/amazon/common"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
// FlatBlockDevice is an auto-generated flat version of BlockDevice.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatBlockDevice struct {
|
||||
DeleteOnTermination *bool `mapstructure:"delete_on_termination" required:"false" cty:"delete_on_termination"`
|
||||
DeviceName *string `mapstructure:"device_name" required:"false" cty:"device_name"`
|
||||
Encrypted *bool `mapstructure:"encrypted" required:"false" cty:"encrypted"`
|
||||
IOPS *int64 `mapstructure:"iops" required:"false" cty:"iops"`
|
||||
NoDevice *bool `mapstructure:"no_device" required:"false" cty:"no_device"`
|
||||
SnapshotId *string `mapstructure:"snapshot_id" required:"false" cty:"snapshot_id"`
|
||||
VirtualName *string `mapstructure:"virtual_name" required:"false" cty:"virtual_name"`
|
||||
VolumeType *string `mapstructure:"volume_type" required:"false" cty:"volume_type"`
|
||||
VolumeSize *int64 `mapstructure:"volume_size" required:"false" cty:"volume_size"`
|
||||
KmsKeyId *string `mapstructure:"kms_key_id" required:"false" cty:"kms_key_id"`
|
||||
OmitFromArtifact *bool `mapstructure:"omit_from_artifact" cty:"omit_from_artifact"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatBlockDevice.
|
||||
// FlatBlockDevice is an auto-generated flat version of BlockDevice.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*BlockDevice) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatBlockDevice)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcl spec of a BlockDevice.
|
||||
// This spec is used by HCL to read the fields of BlockDevice.
|
||||
// The decoded values from this spec will then be applied to a FlatBlockDevice.
|
||||
func (*FlatBlockDevice) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"delete_on_termination": &hcldec.AttrSpec{Name: "delete_on_termination", Type: cty.Bool, Required: false},
|
||||
"device_name": &hcldec.AttrSpec{Name: "device_name", Type: cty.String, Required: false},
|
||||
"encrypted": &hcldec.AttrSpec{Name: "encrypted", Type: cty.Bool, Required: false},
|
||||
"iops": &hcldec.AttrSpec{Name: "iops", Type: cty.Number, Required: false},
|
||||
"no_device": &hcldec.AttrSpec{Name: "no_device", Type: cty.Bool, Required: false},
|
||||
"snapshot_id": &hcldec.AttrSpec{Name: "snapshot_id", Type: cty.String, Required: false},
|
||||
"virtual_name": &hcldec.AttrSpec{Name: "virtual_name", Type: cty.String, Required: false},
|
||||
"volume_type": &hcldec.AttrSpec{Name: "volume_type", Type: cty.String, Required: false},
|
||||
"volume_size": &hcldec.AttrSpec{Name: "volume_size", Type: cty.Number, Required: false},
|
||||
"kms_key_id": &hcldec.AttrSpec{Name: "kms_key_id", Type: cty.String, Required: false},
|
||||
"omit_from_artifact": &hcldec.AttrSpec{Name: "omit_from_artifact", Type: cty.Bool, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatConfig struct {
|
||||
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
|
||||
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
|
||||
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
|
||||
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
|
||||
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
|
||||
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
|
||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
|
||||
AccessKey *string `mapstructure:"access_key" required:"true" cty:"access_key"`
|
||||
CustomEndpointEc2 *string `mapstructure:"custom_endpoint_ec2" required:"false" cty:"custom_endpoint_ec2"`
|
||||
DecodeAuthZMessages *bool `mapstructure:"decode_authorization_messages" required:"false" cty:"decode_authorization_messages"`
|
||||
InsecureSkipTLSVerify *bool `mapstructure:"insecure_skip_tls_verify" required:"false" cty:"insecure_skip_tls_verify"`
|
||||
MFACode *string `mapstructure:"mfa_code" required:"false" cty:"mfa_code"`
|
||||
ProfileName *string `mapstructure:"profile" required:"false" cty:"profile"`
|
||||
RawRegion *string `mapstructure:"region" required:"true" cty:"region"`
|
||||
SecretKey *string `mapstructure:"secret_key" required:"true" cty:"secret_key"`
|
||||
SkipValidation *bool `mapstructure:"skip_region_validation" required:"false" cty:"skip_region_validation"`
|
||||
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check"`
|
||||
Token *string `mapstructure:"token" required:"false" cty:"token"`
|
||||
VaultAWSEngine *common.FlatVaultAWSEngineOptions `mapstructure:"vault_aws_engine" required:"false" cty:"vault_aws_engine"`
|
||||
AssociatePublicIpAddress *bool `mapstructure:"associate_public_ip_address" required:"false" cty:"associate_public_ip_address"`
|
||||
AvailabilityZone *string `mapstructure:"availability_zone" required:"false" cty:"availability_zone"`
|
||||
BlockDurationMinutes *int64 `mapstructure:"block_duration_minutes" required:"false" cty:"block_duration_minutes"`
|
||||
DisableStopInstance *bool `mapstructure:"disable_stop_instance" required:"false" cty:"disable_stop_instance"`
|
||||
EbsOptimized *bool `mapstructure:"ebs_optimized" required:"false" cty:"ebs_optimized"`
|
||||
EnableT2Unlimited *bool `mapstructure:"enable_t2_unlimited" required:"false" cty:"enable_t2_unlimited"`
|
||||
IamInstanceProfile *string `mapstructure:"iam_instance_profile" required:"false" cty:"iam_instance_profile"`
|
||||
SkipProfileValidation *bool `mapstructure:"skip_profile_validation" required:"false" cty:"skip_profile_validation"`
|
||||
TemporaryIamInstanceProfilePolicyDocument *common.FlatPolicyDocument `mapstructure:"temporary_iam_instance_profile_policy_document" required:"false" cty:"temporary_iam_instance_profile_policy_document"`
|
||||
InstanceInitiatedShutdownBehavior *string `mapstructure:"shutdown_behavior" required:"false" cty:"shutdown_behavior"`
|
||||
InstanceType *string `mapstructure:"instance_type" required:"true" cty:"instance_type"`
|
||||
SecurityGroupFilter *common.FlatSecurityGroupFilterOptions `mapstructure:"security_group_filter" required:"false" cty:"security_group_filter"`
|
||||
RunTags map[string]string `mapstructure:"run_tags" required:"false" cty:"run_tags"`
|
||||
SecurityGroupId *string `mapstructure:"security_group_id" required:"false" cty:"security_group_id"`
|
||||
SecurityGroupIds []string `mapstructure:"security_group_ids" required:"false" cty:"security_group_ids"`
|
||||
SourceAmi *string `mapstructure:"source_ami" required:"true" cty:"source_ami"`
|
||||
SourceAmiFilter *common.FlatAmiFilterOptions `mapstructure:"source_ami_filter" required:"false" cty:"source_ami_filter"`
|
||||
SpotInstanceTypes []string `mapstructure:"spot_instance_types" required:"false" cty:"spot_instance_types"`
|
||||
SpotPrice *string `mapstructure:"spot_price" required:"false" cty:"spot_price"`
|
||||
SpotPriceAutoProduct *string `mapstructure:"spot_price_auto_product" required:"false" cty:"spot_price_auto_product"`
|
||||
SpotTags map[string]string `mapstructure:"spot_tags" required:"false" cty:"spot_tags"`
|
||||
SubnetFilter *common.FlatSubnetFilterOptions `mapstructure:"subnet_filter" required:"false" cty:"subnet_filter"`
|
||||
SubnetId *string `mapstructure:"subnet_id" required:"false" cty:"subnet_id"`
|
||||
TemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" required:"false" cty:"temporary_key_pair_name"`
|
||||
TemporarySGSourceCidrs []string `mapstructure:"temporary_security_group_source_cidrs" required:"false" cty:"temporary_security_group_source_cidrs"`
|
||||
UserData *string `mapstructure:"user_data" required:"false" cty:"user_data"`
|
||||
UserDataFile *string `mapstructure:"user_data_file" required:"false" cty:"user_data_file"`
|
||||
VpcFilter *common.FlatVpcFilterOptions `mapstructure:"vpc_filter" required:"false" cty:"vpc_filter"`
|
||||
VpcId *string `mapstructure:"vpc_id" required:"false" cty:"vpc_id"`
|
||||
WindowsPasswordTimeout *string `mapstructure:"windows_password_timeout" required:"false" cty:"windows_password_timeout"`
|
||||
Type *string `mapstructure:"communicator" cty:"communicator"`
|
||||
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"`
|
||||
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host"`
|
||||
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port"`
|
||||
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username"`
|
||||
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password"`
|
||||
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" cty:"ssh_keypair_name"`
|
||||
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys"`
|
||||
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" cty:"ssh_private_key_file"`
|
||||
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty"`
|
||||
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout"`
|
||||
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" cty:"ssh_agent_auth"`
|
||||
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding"`
|
||||
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts"`
|
||||
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host"`
|
||||
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port"`
|
||||
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"`
|
||||
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"`
|
||||
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"`
|
||||
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"`
|
||||
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"`
|
||||
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"`
|
||||
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port"`
|
||||
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username"`
|
||||
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password"`
|
||||
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval"`
|
||||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port"`
|
||||
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout"`
|
||||
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl"`
|
||||
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
|
||||
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
|
||||
SSHInterface *string `mapstructure:"ssh_interface" cty:"ssh_interface"`
|
||||
AMIName *string `mapstructure:"ami_name" required:"true" cty:"ami_name"`
|
||||
AMIDescription *string `mapstructure:"ami_description" required:"false" cty:"ami_description"`
|
||||
AMIVirtType *string `mapstructure:"ami_virtualization_type" required:"false" cty:"ami_virtualization_type"`
|
||||
AMIUsers []string `mapstructure:"ami_users" required:"false" cty:"ami_users"`
|
||||
AMIGroups []string `mapstructure:"ami_groups" required:"false" cty:"ami_groups"`
|
||||
AMIProductCodes []string `mapstructure:"ami_product_codes" required:"false" cty:"ami_product_codes"`
|
||||
AMIRegions []string `mapstructure:"ami_regions" required:"false" cty:"ami_regions"`
|
||||
AMITags common.TagMap `mapstructure:"tags" required:"false" cty:"tags"`
|
||||
AMIENASupport *bool `mapstructure:"ena_support" required:"false" cty:"ena_support"`
|
||||
AMISriovNetSupport *bool `mapstructure:"sriov_support" required:"false" cty:"sriov_support"`
|
||||
AMIForceDeregister *bool `mapstructure:"force_deregister" required:"false" cty:"force_deregister"`
|
||||
AMIForceDeleteSnapshot *bool `mapstructure:"force_delete_snapshot" required:"false" cty:"force_delete_snapshot"`
|
||||
AMIEncryptBootVolume *bool `mapstructure:"encrypt_boot" required:"false" cty:"encrypt_boot"`
|
||||
AMIKmsKeyId *string `mapstructure:"kms_key_id" required:"false" cty:"kms_key_id"`
|
||||
AMIRegionKMSKeyIDs map[string]string `mapstructure:"region_kms_key_ids" required:"false" cty:"region_kms_key_ids"`
|
||||
AMISkipBuildRegion *bool `mapstructure:"skip_save_build_region" cty:"skip_save_build_region"`
|
||||
SnapshotTags common.TagMap `mapstructure:"snapshot_tags" required:"false" cty:"snapshot_tags"`
|
||||
SnapshotUsers []string `mapstructure:"snapshot_users" required:"false" cty:"snapshot_users"`
|
||||
SnapshotGroups []string `mapstructure:"snapshot_groups" required:"false" cty:"snapshot_groups"`
|
||||
AMIMappings []common.FlatBlockDevice `mapstructure:"ami_block_device_mappings" required:"false" cty:"ami_block_device_mappings"`
|
||||
LaunchMappings []FlatBlockDevice `mapstructure:"launch_block_device_mappings" required:"false" cty:"launch_block_device_mappings"`
|
||||
RootDevice *FlatRootBlockDevice `mapstructure:"ami_root_device" required:"true" cty:"ami_root_device"`
|
||||
VolumeRunTags common.TagMap `mapstructure:"run_volume_tags" cty:"run_volume_tags"`
|
||||
Architecture *string `mapstructure:"ami_architecture" required:"false" cty:"ami_architecture"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
|
||||
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
|
||||
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
|
||||
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
|
||||
"packer_user_variables": &hcldec.BlockAttrsSpec{TypeName: "packer_user_variables", ElementType: cty.String, Required: false},
|
||||
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
|
||||
"access_key": &hcldec.AttrSpec{Name: "access_key", Type: cty.String, Required: false},
|
||||
"custom_endpoint_ec2": &hcldec.AttrSpec{Name: "custom_endpoint_ec2", Type: cty.String, Required: false},
|
||||
"decode_authorization_messages": &hcldec.AttrSpec{Name: "decode_authorization_messages", Type: cty.Bool, Required: false},
|
||||
"insecure_skip_tls_verify": &hcldec.AttrSpec{Name: "insecure_skip_tls_verify", Type: cty.Bool, Required: false},
|
||||
"mfa_code": &hcldec.AttrSpec{Name: "mfa_code", Type: cty.String, Required: false},
|
||||
"profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false},
|
||||
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
|
||||
"secret_key": &hcldec.AttrSpec{Name: "secret_key", Type: cty.String, Required: false},
|
||||
"skip_region_validation": &hcldec.AttrSpec{Name: "skip_region_validation", Type: cty.Bool, Required: false},
|
||||
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
|
||||
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
|
||||
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
|
||||
"associate_public_ip_address": &hcldec.AttrSpec{Name: "associate_public_ip_address", Type: cty.Bool, Required: false},
|
||||
"availability_zone": &hcldec.AttrSpec{Name: "availability_zone", Type: cty.String, Required: false},
|
||||
"block_duration_minutes": &hcldec.AttrSpec{Name: "block_duration_minutes", Type: cty.Number, Required: false},
|
||||
"disable_stop_instance": &hcldec.AttrSpec{Name: "disable_stop_instance", Type: cty.Bool, Required: false},
|
||||
"ebs_optimized": &hcldec.AttrSpec{Name: "ebs_optimized", Type: cty.Bool, Required: false},
|
||||
"enable_t2_unlimited": &hcldec.AttrSpec{Name: "enable_t2_unlimited", Type: cty.Bool, Required: false},
|
||||
"iam_instance_profile": &hcldec.AttrSpec{Name: "iam_instance_profile", Type: cty.String, Required: false},
|
||||
"skip_profile_validation": &hcldec.AttrSpec{Name: "skip_profile_validation", Type: cty.Bool, Required: false},
|
||||
"temporary_iam_instance_profile_policy_document": &hcldec.BlockSpec{TypeName: "temporary_iam_instance_profile_policy_document", Nested: hcldec.ObjectSpec((*common.FlatPolicyDocument)(nil).HCL2Spec())},
|
||||
"shutdown_behavior": &hcldec.AttrSpec{Name: "shutdown_behavior", Type: cty.String, Required: false},
|
||||
"instance_type": &hcldec.AttrSpec{Name: "instance_type", Type: cty.String, Required: false},
|
||||
"security_group_filter": &hcldec.BlockSpec{TypeName: "security_group_filter", Nested: hcldec.ObjectSpec((*common.FlatSecurityGroupFilterOptions)(nil).HCL2Spec())},
|
||||
"run_tags": &hcldec.BlockAttrsSpec{TypeName: "run_tags", ElementType: cty.String, Required: false},
|
||||
"security_group_id": &hcldec.AttrSpec{Name: "security_group_id", Type: cty.String, Required: false},
|
||||
"security_group_ids": &hcldec.AttrSpec{Name: "security_group_ids", Type: cty.List(cty.String), Required: false},
|
||||
"source_ami": &hcldec.AttrSpec{Name: "source_ami", Type: cty.String, Required: false},
|
||||
"source_ami_filter": &hcldec.BlockSpec{TypeName: "source_ami_filter", Nested: hcldec.ObjectSpec((*common.FlatAmiFilterOptions)(nil).HCL2Spec())},
|
||||
"spot_instance_types": &hcldec.AttrSpec{Name: "spot_instance_types", Type: cty.List(cty.String), Required: false},
|
||||
"spot_price": &hcldec.AttrSpec{Name: "spot_price", Type: cty.String, Required: false},
|
||||
"spot_price_auto_product": &hcldec.AttrSpec{Name: "spot_price_auto_product", Type: cty.String, Required: false},
|
||||
"spot_tags": &hcldec.BlockAttrsSpec{TypeName: "spot_tags", ElementType: cty.String, Required: false},
|
||||
"subnet_filter": &hcldec.BlockSpec{TypeName: "subnet_filter", Nested: hcldec.ObjectSpec((*common.FlatSubnetFilterOptions)(nil).HCL2Spec())},
|
||||
"subnet_id": &hcldec.AttrSpec{Name: "subnet_id", Type: cty.String, Required: false},
|
||||
"temporary_key_pair_name": &hcldec.AttrSpec{Name: "temporary_key_pair_name", Type: cty.String, Required: false},
|
||||
"temporary_security_group_source_cidrs": &hcldec.AttrSpec{Name: "temporary_security_group_source_cidrs", Type: cty.List(cty.String), Required: false},
|
||||
"user_data": &hcldec.AttrSpec{Name: "user_data", Type: cty.String, Required: false},
|
||||
"user_data_file": &hcldec.AttrSpec{Name: "user_data_file", Type: cty.String, Required: false},
|
||||
"vpc_filter": &hcldec.BlockSpec{TypeName: "vpc_filter", Nested: hcldec.ObjectSpec((*common.FlatVpcFilterOptions)(nil).HCL2Spec())},
|
||||
"vpc_id": &hcldec.AttrSpec{Name: "vpc_id", Type: cty.String, Required: false},
|
||||
"windows_password_timeout": &hcldec.AttrSpec{Name: "windows_password_timeout", Type: cty.String, Required: false},
|
||||
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
|
||||
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
|
||||
"ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false},
|
||||
"ssh_port": &hcldec.AttrSpec{Name: "ssh_port", Type: cty.Number, Required: false},
|
||||
"ssh_username": &hcldec.AttrSpec{Name: "ssh_username", Type: cty.String, Required: false},
|
||||
"ssh_password": &hcldec.AttrSpec{Name: "ssh_password", Type: cty.String, Required: false},
|
||||
"ssh_keypair_name": &hcldec.AttrSpec{Name: "ssh_keypair_name", Type: cty.String, Required: false},
|
||||
"ssh_clear_authorized_keys": &hcldec.AttrSpec{Name: "ssh_clear_authorized_keys", Type: cty.Bool, Required: false},
|
||||
"ssh_private_key_file": &hcldec.AttrSpec{Name: "ssh_private_key_file", Type: cty.String, Required: false},
|
||||
"ssh_pty": &hcldec.AttrSpec{Name: "ssh_pty", Type: cty.Bool, Required: false},
|
||||
"ssh_timeout": &hcldec.AttrSpec{Name: "ssh_timeout", Type: cty.String, Required: false},
|
||||
"ssh_agent_auth": &hcldec.AttrSpec{Name: "ssh_agent_auth", Type: cty.Bool, Required: false},
|
||||
"ssh_disable_agent_forwarding": &hcldec.AttrSpec{Name: "ssh_disable_agent_forwarding", Type: cty.Bool, Required: false},
|
||||
"ssh_handshake_attempts": &hcldec.AttrSpec{Name: "ssh_handshake_attempts", Type: cty.Number, Required: false},
|
||||
"ssh_bastion_host": &hcldec.AttrSpec{Name: "ssh_bastion_host", Type: cty.String, Required: false},
|
||||
"ssh_bastion_port": &hcldec.AttrSpec{Name: "ssh_bastion_port", Type: cty.Number, Required: false},
|
||||
"ssh_bastion_agent_auth": &hcldec.AttrSpec{Name: "ssh_bastion_agent_auth", Type: cty.Bool, Required: false},
|
||||
"ssh_bastion_username": &hcldec.AttrSpec{Name: "ssh_bastion_username", Type: cty.String, Required: false},
|
||||
"ssh_bastion_password": &hcldec.AttrSpec{Name: "ssh_bastion_password", Type: cty.String, Required: false},
|
||||
"ssh_bastion_private_key_file": &hcldec.AttrSpec{Name: "ssh_bastion_private_key_file", Type: cty.String, Required: false},
|
||||
"ssh_file_transfer_method": &hcldec.AttrSpec{Name: "ssh_file_transfer_method", Type: cty.String, Required: false},
|
||||
"ssh_proxy_host": &hcldec.AttrSpec{Name: "ssh_proxy_host", Type: cty.String, Required: false},
|
||||
"ssh_proxy_port": &hcldec.AttrSpec{Name: "ssh_proxy_port", Type: cty.Number, Required: false},
|
||||
"ssh_proxy_username": &hcldec.AttrSpec{Name: "ssh_proxy_username", Type: cty.String, Required: false},
|
||||
"ssh_proxy_password": &hcldec.AttrSpec{Name: "ssh_proxy_password", Type: cty.String, Required: false},
|
||||
"ssh_keep_alive_interval": &hcldec.AttrSpec{Name: "ssh_keep_alive_interval", Type: cty.String, Required: false},
|
||||
"ssh_read_write_timeout": &hcldec.AttrSpec{Name: "ssh_read_write_timeout", Type: cty.String, Required: false},
|
||||
"ssh_remote_tunnels": &hcldec.AttrSpec{Name: "ssh_remote_tunnels", Type: cty.List(cty.String), Required: false},
|
||||
"ssh_local_tunnels": &hcldec.AttrSpec{Name: "ssh_local_tunnels", Type: cty.List(cty.String), Required: false},
|
||||
"ssh_public_key": &hcldec.AttrSpec{Name: "ssh_public_key", Type: cty.List(cty.Number), Required: false},
|
||||
"ssh_private_key": &hcldec.AttrSpec{Name: "ssh_private_key", Type: cty.List(cty.Number), Required: false},
|
||||
"winrm_username": &hcldec.AttrSpec{Name: "winrm_username", Type: cty.String, Required: false},
|
||||
"winrm_password": &hcldec.AttrSpec{Name: "winrm_password", Type: cty.String, Required: false},
|
||||
"winrm_host": &hcldec.AttrSpec{Name: "winrm_host", Type: cty.String, Required: false},
|
||||
"winrm_port": &hcldec.AttrSpec{Name: "winrm_port", Type: cty.Number, Required: false},
|
||||
"winrm_timeout": &hcldec.AttrSpec{Name: "winrm_timeout", Type: cty.String, Required: false},
|
||||
"winrm_use_ssl": &hcldec.AttrSpec{Name: "winrm_use_ssl", Type: cty.Bool, Required: false},
|
||||
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
|
||||
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
|
||||
"ssh_interface": &hcldec.AttrSpec{Name: "ssh_interface", Type: cty.String, Required: false},
|
||||
"ami_name": &hcldec.AttrSpec{Name: "ami_name", Type: cty.String, Required: false},
|
||||
"ami_description": &hcldec.AttrSpec{Name: "ami_description", Type: cty.String, Required: false},
|
||||
"ami_virtualization_type": &hcldec.AttrSpec{Name: "ami_virtualization_type", Type: cty.String, Required: false},
|
||||
"ami_users": &hcldec.AttrSpec{Name: "ami_users", Type: cty.List(cty.String), Required: false},
|
||||
"ami_groups": &hcldec.AttrSpec{Name: "ami_groups", Type: cty.List(cty.String), Required: false},
|
||||
"ami_product_codes": &hcldec.AttrSpec{Name: "ami_product_codes", Type: cty.List(cty.String), Required: false},
|
||||
"ami_regions": &hcldec.AttrSpec{Name: "ami_regions", Type: cty.List(cty.String), Required: false},
|
||||
"tags": &hcldec.BlockAttrsSpec{TypeName: "tags", ElementType: cty.String, Required: false},
|
||||
"ena_support": &hcldec.AttrSpec{Name: "ena_support", Type: cty.Bool, Required: false},
|
||||
"sriov_support": &hcldec.AttrSpec{Name: "sriov_support", Type: cty.Bool, Required: false},
|
||||
"force_deregister": &hcldec.AttrSpec{Name: "force_deregister", Type: cty.Bool, Required: false},
|
||||
"force_delete_snapshot": &hcldec.AttrSpec{Name: "force_delete_snapshot", Type: cty.Bool, Required: false},
|
||||
"encrypt_boot": &hcldec.AttrSpec{Name: "encrypt_boot", Type: cty.Bool, Required: false},
|
||||
"kms_key_id": &hcldec.AttrSpec{Name: "kms_key_id", Type: cty.String, Required: false},
|
||||
"region_kms_key_ids": &hcldec.BlockAttrsSpec{TypeName: "region_kms_key_ids", ElementType: cty.String, Required: false},
|
||||
"skip_save_build_region": &hcldec.AttrSpec{Name: "skip_save_build_region", Type: cty.Bool, Required: false},
|
||||
"snapshot_tags": &hcldec.BlockAttrsSpec{TypeName: "snapshot_tags", ElementType: cty.String, Required: false},
|
||||
"snapshot_users": &hcldec.AttrSpec{Name: "snapshot_users", Type: cty.List(cty.String), Required: false},
|
||||
"snapshot_groups": &hcldec.AttrSpec{Name: "snapshot_groups", Type: cty.List(cty.String), Required: false},
|
||||
"ami_block_device_mappings": &hcldec.BlockListSpec{TypeName: "ami_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
|
||||
"launch_block_device_mappings": &hcldec.BlockListSpec{TypeName: "launch_block_device_mappings", Nested: hcldec.ObjectSpec((*FlatBlockDevice)(nil).HCL2Spec())},
|
||||
"ami_root_device": &hcldec.BlockSpec{TypeName: "ami_root_device", Nested: hcldec.ObjectSpec((*FlatRootBlockDevice)(nil).HCL2Spec())},
|
||||
"run_volume_tags": &hcldec.BlockAttrsSpec{TypeName: "run_volume_tags", ElementType: cty.String, Required: false},
|
||||
"ami_architecture": &hcldec.AttrSpec{Name: "ami_architecture", Type: cty.String, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// FlatRootBlockDevice is an auto-generated flat version of RootBlockDevice.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatRootBlockDevice struct {
|
||||
SourceDeviceName *string `mapstructure:"source_device_name" cty:"source_device_name"`
|
||||
DeviceName *string `mapstructure:"device_name" required:"false" cty:"device_name"`
|
||||
DeleteOnTermination *bool `mapstructure:"delete_on_termination" required:"false" cty:"delete_on_termination"`
|
||||
IOPS *int64 `mapstructure:"iops" required:"false" cty:"iops"`
|
||||
VolumeType *string `mapstructure:"volume_type" required:"false" cty:"volume_type"`
|
||||
VolumeSize *int64 `mapstructure:"volume_size" required:"false" cty:"volume_size"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatRootBlockDevice.
|
||||
// FlatRootBlockDevice is an auto-generated flat version of RootBlockDevice.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*RootBlockDevice) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatRootBlockDevice)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcl spec of a RootBlockDevice.
|
||||
// This spec is used by HCL to read the fields of RootBlockDevice.
|
||||
// The decoded values from this spec will then be applied to a FlatRootBlockDevice.
|
||||
func (*FlatRootBlockDevice) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"source_device_name": &hcldec.AttrSpec{Name: "source_device_name", Type: cty.String, Required: false},
|
||||
"device_name": &hcldec.AttrSpec{Name: "device_name", Type: cty.String, Required: false},
|
||||
"delete_on_termination": &hcldec.AttrSpec{Name: "delete_on_termination", Type: cty.Bool, Required: false},
|
||||
"iops": &hcldec.AttrSpec{Name: "iops", Type: cty.Number, Required: false},
|
||||
"volume_type": &hcldec.AttrSpec{Name: "volume_type", Type: cty.String, Required: false},
|
||||
"volume_size": &hcldec.AttrSpec{Name: "volume_size", Type: cty.Number, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
|
@ -31,7 +31,7 @@ func TestBuilder_Prepare_BadType(t *testing.T) {
|
|||
"access_key": []string{},
|
||||
}
|
||||
|
||||
warnings, err := b.Prepare(c)
|
||||
_, warnings, err := b.Prepare(c)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
|||
|
||||
// Add a random key
|
||||
config["i_should_not_be_valid"] = true
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//go:generate struct-markdown
|
||||
//go:generate mapstructure-to-hcl2 -type Config,BlockDevice
|
||||
|
||||
// The ebsvolume package contains a packer.Builder implementation that builds
|
||||
// EBS volumes for Amazon EC2 using an ephemeral instance,
|
||||
|
@ -10,6 +11,7 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
awscommon "github.com/hashicorp/packer/builder/amazon/common"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
|
@ -79,7 +81,9 @@ type EngineVarsTemplate struct {
|
|||
SourceAMI string
|
||||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
b.config.ctx.Funcs = awscommon.TemplateFuncs
|
||||
// Create passthrough for {{ .BuildRegion }} and {{ .SourceAMI }} variables
|
||||
// so we can fill them in later
|
||||
|
@ -92,7 +96,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
InterpolateContext: &b.config.ctx,
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Accumulate any errors
|
||||
|
@ -129,11 +133,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return warns, errs
|
||||
return nil, warns, errs
|
||||
}
|
||||
|
||||
packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token)
|
||||
return warns, nil
|
||||
return nil, warns, nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||
|
@ -227,6 +231,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
},
|
||||
&awscommon.StepIamInstanceProfile{
|
||||
IamInstanceProfile: b.config.IamInstanceProfile,
|
||||
SkipProfileValidation: b.config.SkipProfileValidation,
|
||||
TemporaryIamInstanceProfilePolicyDocument: b.config.TemporaryIamInstanceProfilePolicyDocument,
|
||||
},
|
||||
instanceStep,
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
// Code generated by "mapstructure-to-hcl2 -type Config,BlockDevice"; DO NOT EDIT.
|
||||
package ebsvolume
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/builder/amazon/common"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
// FlatBlockDevice is an auto-generated flat version of BlockDevice.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatBlockDevice struct {
|
||||
DeleteOnTermination *bool `mapstructure:"delete_on_termination" required:"false" cty:"delete_on_termination"`
|
||||
DeviceName *string `mapstructure:"device_name" required:"false" cty:"device_name"`
|
||||
Encrypted *bool `mapstructure:"encrypted" required:"false" cty:"encrypted"`
|
||||
IOPS *int64 `mapstructure:"iops" required:"false" cty:"iops"`
|
||||
NoDevice *bool `mapstructure:"no_device" required:"false" cty:"no_device"`
|
||||
SnapshotId *string `mapstructure:"snapshot_id" required:"false" cty:"snapshot_id"`
|
||||
VirtualName *string `mapstructure:"virtual_name" required:"false" cty:"virtual_name"`
|
||||
VolumeType *string `mapstructure:"volume_type" required:"false" cty:"volume_type"`
|
||||
VolumeSize *int64 `mapstructure:"volume_size" required:"false" cty:"volume_size"`
|
||||
KmsKeyId *string `mapstructure:"kms_key_id" required:"false" cty:"kms_key_id"`
|
||||
Tags common.TagMap `mapstructure:"tags" required:"false" cty:"tags"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatBlockDevice.
|
||||
// FlatBlockDevice is an auto-generated flat version of BlockDevice.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*BlockDevice) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatBlockDevice)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcl spec of a BlockDevice.
|
||||
// This spec is used by HCL to read the fields of BlockDevice.
|
||||
// The decoded values from this spec will then be applied to a FlatBlockDevice.
|
||||
func (*FlatBlockDevice) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"delete_on_termination": &hcldec.AttrSpec{Name: "delete_on_termination", Type: cty.Bool, Required: false},
|
||||
"device_name": &hcldec.AttrSpec{Name: "device_name", Type: cty.String, Required: false},
|
||||
"encrypted": &hcldec.AttrSpec{Name: "encrypted", Type: cty.Bool, Required: false},
|
||||
"iops": &hcldec.AttrSpec{Name: "iops", Type: cty.Number, Required: false},
|
||||
"no_device": &hcldec.AttrSpec{Name: "no_device", Type: cty.Bool, Required: false},
|
||||
"snapshot_id": &hcldec.AttrSpec{Name: "snapshot_id", Type: cty.String, Required: false},
|
||||
"virtual_name": &hcldec.AttrSpec{Name: "virtual_name", Type: cty.String, Required: false},
|
||||
"volume_type": &hcldec.AttrSpec{Name: "volume_type", Type: cty.String, Required: false},
|
||||
"volume_size": &hcldec.AttrSpec{Name: "volume_size", Type: cty.Number, Required: false},
|
||||
"kms_key_id": &hcldec.AttrSpec{Name: "kms_key_id", Type: cty.String, Required: false},
|
||||
"tags": &hcldec.BlockAttrsSpec{TypeName: "tags", ElementType: cty.String, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatConfig struct {
|
||||
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
|
||||
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
|
||||
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
|
||||
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
|
||||
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
|
||||
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
|
||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
|
||||
AccessKey *string `mapstructure:"access_key" required:"true" cty:"access_key"`
|
||||
CustomEndpointEc2 *string `mapstructure:"custom_endpoint_ec2" required:"false" cty:"custom_endpoint_ec2"`
|
||||
DecodeAuthZMessages *bool `mapstructure:"decode_authorization_messages" required:"false" cty:"decode_authorization_messages"`
|
||||
InsecureSkipTLSVerify *bool `mapstructure:"insecure_skip_tls_verify" required:"false" cty:"insecure_skip_tls_verify"`
|
||||
MFACode *string `mapstructure:"mfa_code" required:"false" cty:"mfa_code"`
|
||||
ProfileName *string `mapstructure:"profile" required:"false" cty:"profile"`
|
||||
RawRegion *string `mapstructure:"region" required:"true" cty:"region"`
|
||||
SecretKey *string `mapstructure:"secret_key" required:"true" cty:"secret_key"`
|
||||
SkipValidation *bool `mapstructure:"skip_region_validation" required:"false" cty:"skip_region_validation"`
|
||||
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check"`
|
||||
Token *string `mapstructure:"token" required:"false" cty:"token"`
|
||||
VaultAWSEngine *common.FlatVaultAWSEngineOptions `mapstructure:"vault_aws_engine" required:"false" cty:"vault_aws_engine"`
|
||||
AssociatePublicIpAddress *bool `mapstructure:"associate_public_ip_address" required:"false" cty:"associate_public_ip_address"`
|
||||
AvailabilityZone *string `mapstructure:"availability_zone" required:"false" cty:"availability_zone"`
|
||||
BlockDurationMinutes *int64 `mapstructure:"block_duration_minutes" required:"false" cty:"block_duration_minutes"`
|
||||
DisableStopInstance *bool `mapstructure:"disable_stop_instance" required:"false" cty:"disable_stop_instance"`
|
||||
EbsOptimized *bool `mapstructure:"ebs_optimized" required:"false" cty:"ebs_optimized"`
|
||||
EnableT2Unlimited *bool `mapstructure:"enable_t2_unlimited" required:"false" cty:"enable_t2_unlimited"`
|
||||
IamInstanceProfile *string `mapstructure:"iam_instance_profile" required:"false" cty:"iam_instance_profile"`
|
||||
SkipProfileValidation *bool `mapstructure:"skip_profile_validation" required:"false" cty:"skip_profile_validation"`
|
||||
TemporaryIamInstanceProfilePolicyDocument *common.FlatPolicyDocument `mapstructure:"temporary_iam_instance_profile_policy_document" required:"false" cty:"temporary_iam_instance_profile_policy_document"`
|
||||
InstanceInitiatedShutdownBehavior *string `mapstructure:"shutdown_behavior" required:"false" cty:"shutdown_behavior"`
|
||||
InstanceType *string `mapstructure:"instance_type" required:"true" cty:"instance_type"`
|
||||
SecurityGroupFilter *common.FlatSecurityGroupFilterOptions `mapstructure:"security_group_filter" required:"false" cty:"security_group_filter"`
|
||||
RunTags map[string]string `mapstructure:"run_tags" required:"false" cty:"run_tags"`
|
||||
SecurityGroupId *string `mapstructure:"security_group_id" required:"false" cty:"security_group_id"`
|
||||
SecurityGroupIds []string `mapstructure:"security_group_ids" required:"false" cty:"security_group_ids"`
|
||||
SourceAmi *string `mapstructure:"source_ami" required:"true" cty:"source_ami"`
|
||||
SourceAmiFilter *common.FlatAmiFilterOptions `mapstructure:"source_ami_filter" required:"false" cty:"source_ami_filter"`
|
||||
SpotInstanceTypes []string `mapstructure:"spot_instance_types" required:"false" cty:"spot_instance_types"`
|
||||
SpotPrice *string `mapstructure:"spot_price" required:"false" cty:"spot_price"`
|
||||
SpotPriceAutoProduct *string `mapstructure:"spot_price_auto_product" required:"false" cty:"spot_price_auto_product"`
|
||||
SpotTags map[string]string `mapstructure:"spot_tags" required:"false" cty:"spot_tags"`
|
||||
SubnetFilter *common.FlatSubnetFilterOptions `mapstructure:"subnet_filter" required:"false" cty:"subnet_filter"`
|
||||
SubnetId *string `mapstructure:"subnet_id" required:"false" cty:"subnet_id"`
|
||||
TemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" required:"false" cty:"temporary_key_pair_name"`
|
||||
TemporarySGSourceCidrs []string `mapstructure:"temporary_security_group_source_cidrs" required:"false" cty:"temporary_security_group_source_cidrs"`
|
||||
UserData *string `mapstructure:"user_data" required:"false" cty:"user_data"`
|
||||
UserDataFile *string `mapstructure:"user_data_file" required:"false" cty:"user_data_file"`
|
||||
VpcFilter *common.FlatVpcFilterOptions `mapstructure:"vpc_filter" required:"false" cty:"vpc_filter"`
|
||||
VpcId *string `mapstructure:"vpc_id" required:"false" cty:"vpc_id"`
|
||||
WindowsPasswordTimeout *string `mapstructure:"windows_password_timeout" required:"false" cty:"windows_password_timeout"`
|
||||
Type *string `mapstructure:"communicator" cty:"communicator"`
|
||||
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"`
|
||||
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host"`
|
||||
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port"`
|
||||
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username"`
|
||||
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password"`
|
||||
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" cty:"ssh_keypair_name"`
|
||||
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys"`
|
||||
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" cty:"ssh_private_key_file"`
|
||||
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty"`
|
||||
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout"`
|
||||
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" cty:"ssh_agent_auth"`
|
||||
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding"`
|
||||
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts"`
|
||||
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host"`
|
||||
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port"`
|
||||
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"`
|
||||
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"`
|
||||
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"`
|
||||
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"`
|
||||
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"`
|
||||
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"`
|
||||
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port"`
|
||||
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username"`
|
||||
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password"`
|
||||
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval"`
|
||||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port"`
|
||||
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout"`
|
||||
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl"`
|
||||
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
|
||||
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
|
||||
SSHInterface *string `mapstructure:"ssh_interface" cty:"ssh_interface"`
|
||||
AMIENASupport *bool `mapstructure:"ena_support" required:"false" cty:"ena_support"`
|
||||
AMISriovNetSupport *bool `mapstructure:"sriov_support" required:"false" cty:"sriov_support"`
|
||||
VolumeMappings []FlatBlockDevice `mapstructure:"ebs_volumes" required:"false" cty:"ebs_volumes"`
|
||||
VolumeRunTags common.TagMap `mapstructure:"run_volume_tags" cty:"run_volume_tags"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
|
||||
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
|
||||
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
|
||||
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
|
||||
"packer_user_variables": &hcldec.BlockAttrsSpec{TypeName: "packer_user_variables", ElementType: cty.String, Required: false},
|
||||
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
|
||||
"access_key": &hcldec.AttrSpec{Name: "access_key", Type: cty.String, Required: false},
|
||||
"custom_endpoint_ec2": &hcldec.AttrSpec{Name: "custom_endpoint_ec2", Type: cty.String, Required: false},
|
||||
"decode_authorization_messages": &hcldec.AttrSpec{Name: "decode_authorization_messages", Type: cty.Bool, Required: false},
|
||||
"insecure_skip_tls_verify": &hcldec.AttrSpec{Name: "insecure_skip_tls_verify", Type: cty.Bool, Required: false},
|
||||
"mfa_code": &hcldec.AttrSpec{Name: "mfa_code", Type: cty.String, Required: false},
|
||||
"profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false},
|
||||
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
|
||||
"secret_key": &hcldec.AttrSpec{Name: "secret_key", Type: cty.String, Required: false},
|
||||
"skip_region_validation": &hcldec.AttrSpec{Name: "skip_region_validation", Type: cty.Bool, Required: false},
|
||||
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
|
||||
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
|
||||
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
|
||||
"associate_public_ip_address": &hcldec.AttrSpec{Name: "associate_public_ip_address", Type: cty.Bool, Required: false},
|
||||
"availability_zone": &hcldec.AttrSpec{Name: "availability_zone", Type: cty.String, Required: false},
|
||||
"block_duration_minutes": &hcldec.AttrSpec{Name: "block_duration_minutes", Type: cty.Number, Required: false},
|
||||
"disable_stop_instance": &hcldec.AttrSpec{Name: "disable_stop_instance", Type: cty.Bool, Required: false},
|
||||
"ebs_optimized": &hcldec.AttrSpec{Name: "ebs_optimized", Type: cty.Bool, Required: false},
|
||||
"enable_t2_unlimited": &hcldec.AttrSpec{Name: "enable_t2_unlimited", Type: cty.Bool, Required: false},
|
||||
"iam_instance_profile": &hcldec.AttrSpec{Name: "iam_instance_profile", Type: cty.String, Required: false},
|
||||
"skip_profile_validation": &hcldec.AttrSpec{Name: "skip_profile_validation", Type: cty.Bool, Required: false},
|
||||
"temporary_iam_instance_profile_policy_document": &hcldec.BlockSpec{TypeName: "temporary_iam_instance_profile_policy_document", Nested: hcldec.ObjectSpec((*common.FlatPolicyDocument)(nil).HCL2Spec())},
|
||||
"shutdown_behavior": &hcldec.AttrSpec{Name: "shutdown_behavior", Type: cty.String, Required: false},
|
||||
"instance_type": &hcldec.AttrSpec{Name: "instance_type", Type: cty.String, Required: false},
|
||||
"security_group_filter": &hcldec.BlockSpec{TypeName: "security_group_filter", Nested: hcldec.ObjectSpec((*common.FlatSecurityGroupFilterOptions)(nil).HCL2Spec())},
|
||||
"run_tags": &hcldec.BlockAttrsSpec{TypeName: "run_tags", ElementType: cty.String, Required: false},
|
||||
"security_group_id": &hcldec.AttrSpec{Name: "security_group_id", Type: cty.String, Required: false},
|
||||
"security_group_ids": &hcldec.AttrSpec{Name: "security_group_ids", Type: cty.List(cty.String), Required: false},
|
||||
"source_ami": &hcldec.AttrSpec{Name: "source_ami", Type: cty.String, Required: false},
|
||||
"source_ami_filter": &hcldec.BlockSpec{TypeName: "source_ami_filter", Nested: hcldec.ObjectSpec((*common.FlatAmiFilterOptions)(nil).HCL2Spec())},
|
||||
"spot_instance_types": &hcldec.AttrSpec{Name: "spot_instance_types", Type: cty.List(cty.String), Required: false},
|
||||
"spot_price": &hcldec.AttrSpec{Name: "spot_price", Type: cty.String, Required: false},
|
||||
"spot_price_auto_product": &hcldec.AttrSpec{Name: "spot_price_auto_product", Type: cty.String, Required: false},
|
||||
"spot_tags": &hcldec.BlockAttrsSpec{TypeName: "spot_tags", ElementType: cty.String, Required: false},
|
||||
"subnet_filter": &hcldec.BlockSpec{TypeName: "subnet_filter", Nested: hcldec.ObjectSpec((*common.FlatSubnetFilterOptions)(nil).HCL2Spec())},
|
||||
"subnet_id": &hcldec.AttrSpec{Name: "subnet_id", Type: cty.String, Required: false},
|
||||
"temporary_key_pair_name": &hcldec.AttrSpec{Name: "temporary_key_pair_name", Type: cty.String, Required: false},
|
||||
"temporary_security_group_source_cidrs": &hcldec.AttrSpec{Name: "temporary_security_group_source_cidrs", Type: cty.List(cty.String), Required: false},
|
||||
"user_data": &hcldec.AttrSpec{Name: "user_data", Type: cty.String, Required: false},
|
||||
"user_data_file": &hcldec.AttrSpec{Name: "user_data_file", Type: cty.String, Required: false},
|
||||
"vpc_filter": &hcldec.BlockSpec{TypeName: "vpc_filter", Nested: hcldec.ObjectSpec((*common.FlatVpcFilterOptions)(nil).HCL2Spec())},
|
||||
"vpc_id": &hcldec.AttrSpec{Name: "vpc_id", Type: cty.String, Required: false},
|
||||
"windows_password_timeout": &hcldec.AttrSpec{Name: "windows_password_timeout", Type: cty.String, Required: false},
|
||||
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
|
||||
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
|
||||
"ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false},
|
||||
"ssh_port": &hcldec.AttrSpec{Name: "ssh_port", Type: cty.Number, Required: false},
|
||||
"ssh_username": &hcldec.AttrSpec{Name: "ssh_username", Type: cty.String, Required: false},
|
||||
"ssh_password": &hcldec.AttrSpec{Name: "ssh_password", Type: cty.String, Required: false},
|
||||
"ssh_keypair_name": &hcldec.AttrSpec{Name: "ssh_keypair_name", Type: cty.String, Required: false},
|
||||
"ssh_clear_authorized_keys": &hcldec.AttrSpec{Name: "ssh_clear_authorized_keys", Type: cty.Bool, Required: false},
|
||||
"ssh_private_key_file": &hcldec.AttrSpec{Name: "ssh_private_key_file", Type: cty.String, Required: false},
|
||||
"ssh_pty": &hcldec.AttrSpec{Name: "ssh_pty", Type: cty.Bool, Required: false},
|
||||
"ssh_timeout": &hcldec.AttrSpec{Name: "ssh_timeout", Type: cty.String, Required: false},
|
||||
"ssh_agent_auth": &hcldec.AttrSpec{Name: "ssh_agent_auth", Type: cty.Bool, Required: false},
|
||||
"ssh_disable_agent_forwarding": &hcldec.AttrSpec{Name: "ssh_disable_agent_forwarding", Type: cty.Bool, Required: false},
|
||||
"ssh_handshake_attempts": &hcldec.AttrSpec{Name: "ssh_handshake_attempts", Type: cty.Number, Required: false},
|
||||
"ssh_bastion_host": &hcldec.AttrSpec{Name: "ssh_bastion_host", Type: cty.String, Required: false},
|
||||
"ssh_bastion_port": &hcldec.AttrSpec{Name: "ssh_bastion_port", Type: cty.Number, Required: false},
|
||||
"ssh_bastion_agent_auth": &hcldec.AttrSpec{Name: "ssh_bastion_agent_auth", Type: cty.Bool, Required: false},
|
||||
"ssh_bastion_username": &hcldec.AttrSpec{Name: "ssh_bastion_username", Type: cty.String, Required: false},
|
||||
"ssh_bastion_password": &hcldec.AttrSpec{Name: "ssh_bastion_password", Type: cty.String, Required: false},
|
||||
"ssh_bastion_private_key_file": &hcldec.AttrSpec{Name: "ssh_bastion_private_key_file", Type: cty.String, Required: false},
|
||||
"ssh_file_transfer_method": &hcldec.AttrSpec{Name: "ssh_file_transfer_method", Type: cty.String, Required: false},
|
||||
"ssh_proxy_host": &hcldec.AttrSpec{Name: "ssh_proxy_host", Type: cty.String, Required: false},
|
||||
"ssh_proxy_port": &hcldec.AttrSpec{Name: "ssh_proxy_port", Type: cty.Number, Required: false},
|
||||
"ssh_proxy_username": &hcldec.AttrSpec{Name: "ssh_proxy_username", Type: cty.String, Required: false},
|
||||
"ssh_proxy_password": &hcldec.AttrSpec{Name: "ssh_proxy_password", Type: cty.String, Required: false},
|
||||
"ssh_keep_alive_interval": &hcldec.AttrSpec{Name: "ssh_keep_alive_interval", Type: cty.String, Required: false},
|
||||
"ssh_read_write_timeout": &hcldec.AttrSpec{Name: "ssh_read_write_timeout", Type: cty.String, Required: false},
|
||||
"ssh_remote_tunnels": &hcldec.AttrSpec{Name: "ssh_remote_tunnels", Type: cty.List(cty.String), Required: false},
|
||||
"ssh_local_tunnels": &hcldec.AttrSpec{Name: "ssh_local_tunnels", Type: cty.List(cty.String), Required: false},
|
||||
"ssh_public_key": &hcldec.AttrSpec{Name: "ssh_public_key", Type: cty.List(cty.Number), Required: false},
|
||||
"ssh_private_key": &hcldec.AttrSpec{Name: "ssh_private_key", Type: cty.List(cty.Number), Required: false},
|
||||
"winrm_username": &hcldec.AttrSpec{Name: "winrm_username", Type: cty.String, Required: false},
|
||||
"winrm_password": &hcldec.AttrSpec{Name: "winrm_password", Type: cty.String, Required: false},
|
||||
"winrm_host": &hcldec.AttrSpec{Name: "winrm_host", Type: cty.String, Required: false},
|
||||
"winrm_port": &hcldec.AttrSpec{Name: "winrm_port", Type: cty.Number, Required: false},
|
||||
"winrm_timeout": &hcldec.AttrSpec{Name: "winrm_timeout", Type: cty.String, Required: false},
|
||||
"winrm_use_ssl": &hcldec.AttrSpec{Name: "winrm_use_ssl", Type: cty.Bool, Required: false},
|
||||
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
|
||||
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
|
||||
"ssh_interface": &hcldec.AttrSpec{Name: "ssh_interface", Type: cty.String, Required: false},
|
||||
"ena_support": &hcldec.AttrSpec{Name: "ena_support", Type: cty.Bool, Required: false},
|
||||
"sriov_support": &hcldec.AttrSpec{Name: "sriov_support", Type: cty.Bool, Required: false},
|
||||
"ebs_volumes": &hcldec.BlockListSpec{TypeName: "ebs_volumes", Nested: hcldec.ObjectSpec((*FlatBlockDevice)(nil).HCL2Spec())},
|
||||
"run_volume_tags": &hcldec.BlockAttrsSpec{TypeName: "run_volume_tags", ElementType: cty.String, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
|
@ -31,7 +31,7 @@ func TestBuilder_Prepare_BadType(t *testing.T) {
|
|||
"access_key": []string{},
|
||||
}
|
||||
|
||||
warnings, err := b.Prepare(c)
|
||||
_, warnings, err := b.Prepare(c)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
|||
|
||||
// Add a random key
|
||||
config["i_should_not_be_valid"] = true
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ func TestBuilderPrepare_InvalidShutdownBehavior(t *testing.T) {
|
|||
// Test good
|
||||
config["shutdown_behavior"] = "terminate"
|
||||
config["skip_region_validation"] = true
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ func TestBuilderPrepare_InvalidShutdownBehavior(t *testing.T) {
|
|||
|
||||
// Test good
|
||||
config["shutdown_behavior"] = "stop"
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ func TestBuilderPrepare_InvalidShutdownBehavior(t *testing.T) {
|
|||
|
||||
// Test bad
|
||||
config["shutdown_behavior"] = "foobar"
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//go:generate struct-markdown
|
||||
//go:generate mapstructure-to-hcl2 -type Config
|
||||
|
||||
// The instance package contains a packer.Builder implementation that builds
|
||||
// AMIs for Amazon EC2 backed by instance storage, as opposed to EBS storage.
|
||||
|
@ -13,6 +14,7 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
awscommon "github.com/hashicorp/packer/builder/amazon/common"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
|
@ -93,7 +95,9 @@ type Builder struct {
|
|||
runner multistep.Runner
|
||||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
configs := make([]interface{}, len(raws)+1)
|
||||
configs[0] = map[string]interface{}{
|
||||
"bundle_prefix": "image-{{timestamp}}",
|
||||
|
@ -118,7 +122,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
},
|
||||
}, configs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if b.config.PackerConfig.PackerForce {
|
||||
|
@ -218,10 +222,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return warns, errs
|
||||
return nil, warns, errs
|
||||
}
|
||||
packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token)
|
||||
return warns, nil
|
||||
return nil, warns, nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||
|
@ -318,6 +322,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
},
|
||||
&awscommon.StepIamInstanceProfile{
|
||||
IamInstanceProfile: b.config.IamInstanceProfile,
|
||||
SkipProfileValidation: b.config.SkipProfileValidation,
|
||||
TemporaryIamInstanceProfilePolicyDocument: b.config.TemporaryIamInstanceProfilePolicyDocument,
|
||||
},
|
||||
instanceStep,
|
||||
|
|
|
@ -0,0 +1,267 @@
|
|||
// Code generated by "mapstructure-to-hcl2 -type Config"; DO NOT EDIT.
|
||||
package instance
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/builder/amazon/common"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatConfig struct {
|
||||
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
|
||||
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
|
||||
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
|
||||
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
|
||||
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
|
||||
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
|
||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
|
||||
AccessKey *string `mapstructure:"access_key" required:"true" cty:"access_key"`
|
||||
CustomEndpointEc2 *string `mapstructure:"custom_endpoint_ec2" required:"false" cty:"custom_endpoint_ec2"`
|
||||
DecodeAuthZMessages *bool `mapstructure:"decode_authorization_messages" required:"false" cty:"decode_authorization_messages"`
|
||||
InsecureSkipTLSVerify *bool `mapstructure:"insecure_skip_tls_verify" required:"false" cty:"insecure_skip_tls_verify"`
|
||||
MFACode *string `mapstructure:"mfa_code" required:"false" cty:"mfa_code"`
|
||||
ProfileName *string `mapstructure:"profile" required:"false" cty:"profile"`
|
||||
RawRegion *string `mapstructure:"region" required:"true" cty:"region"`
|
||||
SecretKey *string `mapstructure:"secret_key" required:"true" cty:"secret_key"`
|
||||
SkipValidation *bool `mapstructure:"skip_region_validation" required:"false" cty:"skip_region_validation"`
|
||||
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check"`
|
||||
Token *string `mapstructure:"token" required:"false" cty:"token"`
|
||||
VaultAWSEngine *common.FlatVaultAWSEngineOptions `mapstructure:"vault_aws_engine" required:"false" cty:"vault_aws_engine"`
|
||||
AMIName *string `mapstructure:"ami_name" required:"true" cty:"ami_name"`
|
||||
AMIDescription *string `mapstructure:"ami_description" required:"false" cty:"ami_description"`
|
||||
AMIVirtType *string `mapstructure:"ami_virtualization_type" required:"false" cty:"ami_virtualization_type"`
|
||||
AMIUsers []string `mapstructure:"ami_users" required:"false" cty:"ami_users"`
|
||||
AMIGroups []string `mapstructure:"ami_groups" required:"false" cty:"ami_groups"`
|
||||
AMIProductCodes []string `mapstructure:"ami_product_codes" required:"false" cty:"ami_product_codes"`
|
||||
AMIRegions []string `mapstructure:"ami_regions" required:"false" cty:"ami_regions"`
|
||||
AMITags common.TagMap `mapstructure:"tags" required:"false" cty:"tags"`
|
||||
AMIENASupport *bool `mapstructure:"ena_support" required:"false" cty:"ena_support"`
|
||||
AMISriovNetSupport *bool `mapstructure:"sriov_support" required:"false" cty:"sriov_support"`
|
||||
AMIForceDeregister *bool `mapstructure:"force_deregister" required:"false" cty:"force_deregister"`
|
||||
AMIForceDeleteSnapshot *bool `mapstructure:"force_delete_snapshot" required:"false" cty:"force_delete_snapshot"`
|
||||
AMIEncryptBootVolume *bool `mapstructure:"encrypt_boot" required:"false" cty:"encrypt_boot"`
|
||||
AMIKmsKeyId *string `mapstructure:"kms_key_id" required:"false" cty:"kms_key_id"`
|
||||
AMIRegionKMSKeyIDs map[string]string `mapstructure:"region_kms_key_ids" required:"false" cty:"region_kms_key_ids"`
|
||||
AMISkipBuildRegion *bool `mapstructure:"skip_save_build_region" cty:"skip_save_build_region"`
|
||||
SnapshotTags common.TagMap `mapstructure:"snapshot_tags" required:"false" cty:"snapshot_tags"`
|
||||
SnapshotUsers []string `mapstructure:"snapshot_users" required:"false" cty:"snapshot_users"`
|
||||
SnapshotGroups []string `mapstructure:"snapshot_groups" required:"false" cty:"snapshot_groups"`
|
||||
AssociatePublicIpAddress *bool `mapstructure:"associate_public_ip_address" required:"false" cty:"associate_public_ip_address"`
|
||||
AvailabilityZone *string `mapstructure:"availability_zone" required:"false" cty:"availability_zone"`
|
||||
BlockDurationMinutes *int64 `mapstructure:"block_duration_minutes" required:"false" cty:"block_duration_minutes"`
|
||||
DisableStopInstance *bool `mapstructure:"disable_stop_instance" required:"false" cty:"disable_stop_instance"`
|
||||
EbsOptimized *bool `mapstructure:"ebs_optimized" required:"false" cty:"ebs_optimized"`
|
||||
EnableT2Unlimited *bool `mapstructure:"enable_t2_unlimited" required:"false" cty:"enable_t2_unlimited"`
|
||||
IamInstanceProfile *string `mapstructure:"iam_instance_profile" required:"false" cty:"iam_instance_profile"`
|
||||
SkipProfileValidation *bool `mapstructure:"skip_profile_validation" required:"false" cty:"skip_profile_validation"`
|
||||
TemporaryIamInstanceProfilePolicyDocument *common.FlatPolicyDocument `mapstructure:"temporary_iam_instance_profile_policy_document" required:"false" cty:"temporary_iam_instance_profile_policy_document"`
|
||||
InstanceInitiatedShutdownBehavior *string `mapstructure:"shutdown_behavior" required:"false" cty:"shutdown_behavior"`
|
||||
InstanceType *string `mapstructure:"instance_type" required:"true" cty:"instance_type"`
|
||||
SecurityGroupFilter *common.FlatSecurityGroupFilterOptions `mapstructure:"security_group_filter" required:"false" cty:"security_group_filter"`
|
||||
RunTags map[string]string `mapstructure:"run_tags" required:"false" cty:"run_tags"`
|
||||
SecurityGroupId *string `mapstructure:"security_group_id" required:"false" cty:"security_group_id"`
|
||||
SecurityGroupIds []string `mapstructure:"security_group_ids" required:"false" cty:"security_group_ids"`
|
||||
SourceAmi *string `mapstructure:"source_ami" required:"true" cty:"source_ami"`
|
||||
SourceAmiFilter *common.FlatAmiFilterOptions `mapstructure:"source_ami_filter" required:"false" cty:"source_ami_filter"`
|
||||
SpotInstanceTypes []string `mapstructure:"spot_instance_types" required:"false" cty:"spot_instance_types"`
|
||||
SpotPrice *string `mapstructure:"spot_price" required:"false" cty:"spot_price"`
|
||||
SpotPriceAutoProduct *string `mapstructure:"spot_price_auto_product" required:"false" cty:"spot_price_auto_product"`
|
||||
SpotTags map[string]string `mapstructure:"spot_tags" required:"false" cty:"spot_tags"`
|
||||
SubnetFilter *common.FlatSubnetFilterOptions `mapstructure:"subnet_filter" required:"false" cty:"subnet_filter"`
|
||||
SubnetId *string `mapstructure:"subnet_id" required:"false" cty:"subnet_id"`
|
||||
TemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" required:"false" cty:"temporary_key_pair_name"`
|
||||
TemporarySGSourceCidrs []string `mapstructure:"temporary_security_group_source_cidrs" required:"false" cty:"temporary_security_group_source_cidrs"`
|
||||
UserData *string `mapstructure:"user_data" required:"false" cty:"user_data"`
|
||||
UserDataFile *string `mapstructure:"user_data_file" required:"false" cty:"user_data_file"`
|
||||
VpcFilter *common.FlatVpcFilterOptions `mapstructure:"vpc_filter" required:"false" cty:"vpc_filter"`
|
||||
VpcId *string `mapstructure:"vpc_id" required:"false" cty:"vpc_id"`
|
||||
WindowsPasswordTimeout *string `mapstructure:"windows_password_timeout" required:"false" cty:"windows_password_timeout"`
|
||||
Type *string `mapstructure:"communicator" cty:"communicator"`
|
||||
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"`
|
||||
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host"`
|
||||
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port"`
|
||||
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username"`
|
||||
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password"`
|
||||
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" cty:"ssh_keypair_name"`
|
||||
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys"`
|
||||
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" cty:"ssh_private_key_file"`
|
||||
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty"`
|
||||
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout"`
|
||||
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" cty:"ssh_agent_auth"`
|
||||
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding"`
|
||||
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts"`
|
||||
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host"`
|
||||
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port"`
|
||||
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"`
|
||||
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"`
|
||||
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"`
|
||||
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"`
|
||||
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"`
|
||||
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"`
|
||||
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port"`
|
||||
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username"`
|
||||
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password"`
|
||||
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval"`
|
||||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port"`
|
||||
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout"`
|
||||
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl"`
|
||||
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
|
||||
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
|
||||
SSHInterface *string `mapstructure:"ssh_interface" cty:"ssh_interface"`
|
||||
AMIMappings []common.FlatBlockDevice `mapstructure:"ami_block_device_mappings" required:"false" cty:"ami_block_device_mappings"`
|
||||
LaunchMappings []common.FlatBlockDevice `mapstructure:"launch_block_device_mappings" required:"false" cty:"launch_block_device_mappings"`
|
||||
AccountId *string `mapstructure:"account_id" required:"true" cty:"account_id"`
|
||||
BundleDestination *string `mapstructure:"bundle_destination" required:"false" cty:"bundle_destination"`
|
||||
BundlePrefix *string `mapstructure:"bundle_prefix" required:"false" cty:"bundle_prefix"`
|
||||
BundleUploadCommand *string `mapstructure:"bundle_upload_command" required:"false" cty:"bundle_upload_command"`
|
||||
BundleVolCommand *string `mapstructure:"bundle_vol_command" required:"false" cty:"bundle_vol_command"`
|
||||
S3Bucket *string `mapstructure:"s3_bucket" required:"true" cty:"s3_bucket"`
|
||||
X509CertPath *string `mapstructure:"x509_cert_path" required:"true" cty:"x509_cert_path"`
|
||||
X509KeyPath *string `mapstructure:"x509_key_path" required:"true" cty:"x509_key_path"`
|
||||
X509UploadPath *string `mapstructure:"x509_upload_path" required:"false" cty:"x509_upload_path"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
|
||||
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
|
||||
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
|
||||
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
|
||||
"packer_user_variables": &hcldec.BlockAttrsSpec{TypeName: "packer_user_variables", ElementType: cty.String, Required: false},
|
||||
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
|
||||
"access_key": &hcldec.AttrSpec{Name: "access_key", Type: cty.String, Required: false},
|
||||
"custom_endpoint_ec2": &hcldec.AttrSpec{Name: "custom_endpoint_ec2", Type: cty.String, Required: false},
|
||||
"decode_authorization_messages": &hcldec.AttrSpec{Name: "decode_authorization_messages", Type: cty.Bool, Required: false},
|
||||
"insecure_skip_tls_verify": &hcldec.AttrSpec{Name: "insecure_skip_tls_verify", Type: cty.Bool, Required: false},
|
||||
"mfa_code": &hcldec.AttrSpec{Name: "mfa_code", Type: cty.String, Required: false},
|
||||
"profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false},
|
||||
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
|
||||
"secret_key": &hcldec.AttrSpec{Name: "secret_key", Type: cty.String, Required: false},
|
||||
"skip_region_validation": &hcldec.AttrSpec{Name: "skip_region_validation", Type: cty.Bool, Required: false},
|
||||
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
|
||||
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
|
||||
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
|
||||
"ami_name": &hcldec.AttrSpec{Name: "ami_name", Type: cty.String, Required: false},
|
||||
"ami_description": &hcldec.AttrSpec{Name: "ami_description", Type: cty.String, Required: false},
|
||||
"ami_virtualization_type": &hcldec.AttrSpec{Name: "ami_virtualization_type", Type: cty.String, Required: false},
|
||||
"ami_users": &hcldec.AttrSpec{Name: "ami_users", Type: cty.List(cty.String), Required: false},
|
||||
"ami_groups": &hcldec.AttrSpec{Name: "ami_groups", Type: cty.List(cty.String), Required: false},
|
||||
"ami_product_codes": &hcldec.AttrSpec{Name: "ami_product_codes", Type: cty.List(cty.String), Required: false},
|
||||
"ami_regions": &hcldec.AttrSpec{Name: "ami_regions", Type: cty.List(cty.String), Required: false},
|
||||
"tags": &hcldec.BlockAttrsSpec{TypeName: "tags", ElementType: cty.String, Required: false},
|
||||
"ena_support": &hcldec.AttrSpec{Name: "ena_support", Type: cty.Bool, Required: false},
|
||||
"sriov_support": &hcldec.AttrSpec{Name: "sriov_support", Type: cty.Bool, Required: false},
|
||||
"force_deregister": &hcldec.AttrSpec{Name: "force_deregister", Type: cty.Bool, Required: false},
|
||||
"force_delete_snapshot": &hcldec.AttrSpec{Name: "force_delete_snapshot", Type: cty.Bool, Required: false},
|
||||
"encrypt_boot": &hcldec.AttrSpec{Name: "encrypt_boot", Type: cty.Bool, Required: false},
|
||||
"kms_key_id": &hcldec.AttrSpec{Name: "kms_key_id", Type: cty.String, Required: false},
|
||||
"region_kms_key_ids": &hcldec.BlockAttrsSpec{TypeName: "region_kms_key_ids", ElementType: cty.String, Required: false},
|
||||
"skip_save_build_region": &hcldec.AttrSpec{Name: "skip_save_build_region", Type: cty.Bool, Required: false},
|
||||
"snapshot_tags": &hcldec.BlockAttrsSpec{TypeName: "snapshot_tags", ElementType: cty.String, Required: false},
|
||||
"snapshot_users": &hcldec.AttrSpec{Name: "snapshot_users", Type: cty.List(cty.String), Required: false},
|
||||
"snapshot_groups": &hcldec.AttrSpec{Name: "snapshot_groups", Type: cty.List(cty.String), Required: false},
|
||||
"associate_public_ip_address": &hcldec.AttrSpec{Name: "associate_public_ip_address", Type: cty.Bool, Required: false},
|
||||
"availability_zone": &hcldec.AttrSpec{Name: "availability_zone", Type: cty.String, Required: false},
|
||||
"block_duration_minutes": &hcldec.AttrSpec{Name: "block_duration_minutes", Type: cty.Number, Required: false},
|
||||
"disable_stop_instance": &hcldec.AttrSpec{Name: "disable_stop_instance", Type: cty.Bool, Required: false},
|
||||
"ebs_optimized": &hcldec.AttrSpec{Name: "ebs_optimized", Type: cty.Bool, Required: false},
|
||||
"enable_t2_unlimited": &hcldec.AttrSpec{Name: "enable_t2_unlimited", Type: cty.Bool, Required: false},
|
||||
"iam_instance_profile": &hcldec.AttrSpec{Name: "iam_instance_profile", Type: cty.String, Required: false},
|
||||
"skip_profile_validation": &hcldec.AttrSpec{Name: "skip_profile_validation", Type: cty.Bool, Required: false},
|
||||
"temporary_iam_instance_profile_policy_document": &hcldec.BlockSpec{TypeName: "temporary_iam_instance_profile_policy_document", Nested: hcldec.ObjectSpec((*common.FlatPolicyDocument)(nil).HCL2Spec())},
|
||||
"shutdown_behavior": &hcldec.AttrSpec{Name: "shutdown_behavior", Type: cty.String, Required: false},
|
||||
"instance_type": &hcldec.AttrSpec{Name: "instance_type", Type: cty.String, Required: false},
|
||||
"security_group_filter": &hcldec.BlockSpec{TypeName: "security_group_filter", Nested: hcldec.ObjectSpec((*common.FlatSecurityGroupFilterOptions)(nil).HCL2Spec())},
|
||||
"run_tags": &hcldec.BlockAttrsSpec{TypeName: "run_tags", ElementType: cty.String, Required: false},
|
||||
"security_group_id": &hcldec.AttrSpec{Name: "security_group_id", Type: cty.String, Required: false},
|
||||
"security_group_ids": &hcldec.AttrSpec{Name: "security_group_ids", Type: cty.List(cty.String), Required: false},
|
||||
"source_ami": &hcldec.AttrSpec{Name: "source_ami", Type: cty.String, Required: false},
|
||||
"source_ami_filter": &hcldec.BlockSpec{TypeName: "source_ami_filter", Nested: hcldec.ObjectSpec((*common.FlatAmiFilterOptions)(nil).HCL2Spec())},
|
||||
"spot_instance_types": &hcldec.AttrSpec{Name: "spot_instance_types", Type: cty.List(cty.String), Required: false},
|
||||
"spot_price": &hcldec.AttrSpec{Name: "spot_price", Type: cty.String, Required: false},
|
||||
"spot_price_auto_product": &hcldec.AttrSpec{Name: "spot_price_auto_product", Type: cty.String, Required: false},
|
||||
"spot_tags": &hcldec.BlockAttrsSpec{TypeName: "spot_tags", ElementType: cty.String, Required: false},
|
||||
"subnet_filter": &hcldec.BlockSpec{TypeName: "subnet_filter", Nested: hcldec.ObjectSpec((*common.FlatSubnetFilterOptions)(nil).HCL2Spec())},
|
||||
"subnet_id": &hcldec.AttrSpec{Name: "subnet_id", Type: cty.String, Required: false},
|
||||
"temporary_key_pair_name": &hcldec.AttrSpec{Name: "temporary_key_pair_name", Type: cty.String, Required: false},
|
||||
"temporary_security_group_source_cidrs": &hcldec.AttrSpec{Name: "temporary_security_group_source_cidrs", Type: cty.List(cty.String), Required: false},
|
||||
"user_data": &hcldec.AttrSpec{Name: "user_data", Type: cty.String, Required: false},
|
||||
"user_data_file": &hcldec.AttrSpec{Name: "user_data_file", Type: cty.String, Required: false},
|
||||
"vpc_filter": &hcldec.BlockSpec{TypeName: "vpc_filter", Nested: hcldec.ObjectSpec((*common.FlatVpcFilterOptions)(nil).HCL2Spec())},
|
||||
"vpc_id": &hcldec.AttrSpec{Name: "vpc_id", Type: cty.String, Required: false},
|
||||
"windows_password_timeout": &hcldec.AttrSpec{Name: "windows_password_timeout", Type: cty.String, Required: false},
|
||||
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
|
||||
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
|
||||
"ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false},
|
||||
"ssh_port": &hcldec.AttrSpec{Name: "ssh_port", Type: cty.Number, Required: false},
|
||||
"ssh_username": &hcldec.AttrSpec{Name: "ssh_username", Type: cty.String, Required: false},
|
||||
"ssh_password": &hcldec.AttrSpec{Name: "ssh_password", Type: cty.String, Required: false},
|
||||
"ssh_keypair_name": &hcldec.AttrSpec{Name: "ssh_keypair_name", Type: cty.String, Required: false},
|
||||
"ssh_clear_authorized_keys": &hcldec.AttrSpec{Name: "ssh_clear_authorized_keys", Type: cty.Bool, Required: false},
|
||||
"ssh_private_key_file": &hcldec.AttrSpec{Name: "ssh_private_key_file", Type: cty.String, Required: false},
|
||||
"ssh_pty": &hcldec.AttrSpec{Name: "ssh_pty", Type: cty.Bool, Required: false},
|
||||
"ssh_timeout": &hcldec.AttrSpec{Name: "ssh_timeout", Type: cty.String, Required: false},
|
||||
"ssh_agent_auth": &hcldec.AttrSpec{Name: "ssh_agent_auth", Type: cty.Bool, Required: false},
|
||||
"ssh_disable_agent_forwarding": &hcldec.AttrSpec{Name: "ssh_disable_agent_forwarding", Type: cty.Bool, Required: false},
|
||||
"ssh_handshake_attempts": &hcldec.AttrSpec{Name: "ssh_handshake_attempts", Type: cty.Number, Required: false},
|
||||
"ssh_bastion_host": &hcldec.AttrSpec{Name: "ssh_bastion_host", Type: cty.String, Required: false},
|
||||
"ssh_bastion_port": &hcldec.AttrSpec{Name: "ssh_bastion_port", Type: cty.Number, Required: false},
|
||||
"ssh_bastion_agent_auth": &hcldec.AttrSpec{Name: "ssh_bastion_agent_auth", Type: cty.Bool, Required: false},
|
||||
"ssh_bastion_username": &hcldec.AttrSpec{Name: "ssh_bastion_username", Type: cty.String, Required: false},
|
||||
"ssh_bastion_password": &hcldec.AttrSpec{Name: "ssh_bastion_password", Type: cty.String, Required: false},
|
||||
"ssh_bastion_private_key_file": &hcldec.AttrSpec{Name: "ssh_bastion_private_key_file", Type: cty.String, Required: false},
|
||||
"ssh_file_transfer_method": &hcldec.AttrSpec{Name: "ssh_file_transfer_method", Type: cty.String, Required: false},
|
||||
"ssh_proxy_host": &hcldec.AttrSpec{Name: "ssh_proxy_host", Type: cty.String, Required: false},
|
||||
"ssh_proxy_port": &hcldec.AttrSpec{Name: "ssh_proxy_port", Type: cty.Number, Required: false},
|
||||
"ssh_proxy_username": &hcldec.AttrSpec{Name: "ssh_proxy_username", Type: cty.String, Required: false},
|
||||
"ssh_proxy_password": &hcldec.AttrSpec{Name: "ssh_proxy_password", Type: cty.String, Required: false},
|
||||
"ssh_keep_alive_interval": &hcldec.AttrSpec{Name: "ssh_keep_alive_interval", Type: cty.String, Required: false},
|
||||
"ssh_read_write_timeout": &hcldec.AttrSpec{Name: "ssh_read_write_timeout", Type: cty.String, Required: false},
|
||||
"ssh_remote_tunnels": &hcldec.AttrSpec{Name: "ssh_remote_tunnels", Type: cty.List(cty.String), Required: false},
|
||||
"ssh_local_tunnels": &hcldec.AttrSpec{Name: "ssh_local_tunnels", Type: cty.List(cty.String), Required: false},
|
||||
"ssh_public_key": &hcldec.AttrSpec{Name: "ssh_public_key", Type: cty.List(cty.Number), Required: false},
|
||||
"ssh_private_key": &hcldec.AttrSpec{Name: "ssh_private_key", Type: cty.List(cty.Number), Required: false},
|
||||
"winrm_username": &hcldec.AttrSpec{Name: "winrm_username", Type: cty.String, Required: false},
|
||||
"winrm_password": &hcldec.AttrSpec{Name: "winrm_password", Type: cty.String, Required: false},
|
||||
"winrm_host": &hcldec.AttrSpec{Name: "winrm_host", Type: cty.String, Required: false},
|
||||
"winrm_port": &hcldec.AttrSpec{Name: "winrm_port", Type: cty.Number, Required: false},
|
||||
"winrm_timeout": &hcldec.AttrSpec{Name: "winrm_timeout", Type: cty.String, Required: false},
|
||||
"winrm_use_ssl": &hcldec.AttrSpec{Name: "winrm_use_ssl", Type: cty.Bool, Required: false},
|
||||
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
|
||||
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
|
||||
"ssh_interface": &hcldec.AttrSpec{Name: "ssh_interface", Type: cty.String, Required: false},
|
||||
"ami_block_device_mappings": &hcldec.BlockListSpec{TypeName: "ami_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
|
||||
"launch_block_device_mappings": &hcldec.BlockListSpec{TypeName: "launch_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
|
||||
"account_id": &hcldec.AttrSpec{Name: "account_id", Type: cty.String, Required: false},
|
||||
"bundle_destination": &hcldec.AttrSpec{Name: "bundle_destination", Type: cty.String, Required: false},
|
||||
"bundle_prefix": &hcldec.AttrSpec{Name: "bundle_prefix", Type: cty.String, Required: false},
|
||||
"bundle_upload_command": &hcldec.AttrSpec{Name: "bundle_upload_command", Type: cty.String, Required: false},
|
||||
"bundle_vol_command": &hcldec.AttrSpec{Name: "bundle_vol_command", Type: cty.String, Required: false},
|
||||
"s3_bucket": &hcldec.AttrSpec{Name: "s3_bucket", Type: cty.String, Required: false},
|
||||
"x509_cert_path": &hcldec.AttrSpec{Name: "x509_cert_path", Type: cty.String, Required: false},
|
||||
"x509_key_path": &hcldec.AttrSpec{Name: "x509_key_path", Type: cty.String, Required: false},
|
||||
"x509_upload_path": &hcldec.AttrSpec{Name: "x509_upload_path", Type: cty.String, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
|
@ -47,7 +47,7 @@ func TestBuilderPrepare_AccountId(t *testing.T) {
|
|||
defer tempfile.Close()
|
||||
|
||||
config["account_id"] = ""
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ func TestBuilderPrepare_AccountId(t *testing.T) {
|
|||
}
|
||||
|
||||
config["account_id"] = "foo"
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ func TestBuilderPrepare_AccountId(t *testing.T) {
|
|||
}
|
||||
|
||||
config["account_id"] = "0123-0456-7890"
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ func TestBuilderPrepare_AMIName(t *testing.T) {
|
|||
// Test good
|
||||
config["ami_name"] = "foo"
|
||||
config["skip_region_validation"] = true
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ func TestBuilderPrepare_AMIName(t *testing.T) {
|
|||
// Test bad
|
||||
config["ami_name"] = "foo {{"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ func TestBuilderPrepare_AMIName(t *testing.T) {
|
|||
// Test bad
|
||||
delete(config, "ami_name")
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ func TestBuilderPrepare_BundleDestination(t *testing.T) {
|
|||
defer tempfile.Close()
|
||||
|
||||
config["bundle_destination"] = ""
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ func TestBuilderPrepare_BundlePrefix(t *testing.T) {
|
|||
defer os.Remove(tempfile.Name())
|
||||
defer tempfile.Close()
|
||||
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
|||
|
||||
// Add a random key
|
||||
config["i_should_not_be_valid"] = true
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ func TestBuilderPrepare_S3Bucket(t *testing.T) {
|
|||
defer tempfile.Close()
|
||||
|
||||
config["s3_bucket"] = ""
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ func TestBuilderPrepare_S3Bucket(t *testing.T) {
|
|||
}
|
||||
|
||||
config["s3_bucket"] = "foo"
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ func TestBuilderPrepare_X509CertPath(t *testing.T) {
|
|||
defer tempfile.Close()
|
||||
|
||||
config["x509_cert_path"] = ""
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ func TestBuilderPrepare_X509CertPath(t *testing.T) {
|
|||
}
|
||||
|
||||
config["x509_cert_path"] = "i/am/a/file/that/doesnt/exist"
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ func TestBuilderPrepare_X509CertPath(t *testing.T) {
|
|||
defer tf.Close()
|
||||
|
||||
config["x509_cert_path"] = tf.Name()
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ func TestBuilderPrepare_X509KeyPath(t *testing.T) {
|
|||
defer tempfile.Close()
|
||||
|
||||
config["x509_key_path"] = ""
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ func TestBuilderPrepare_X509KeyPath(t *testing.T) {
|
|||
}
|
||||
|
||||
config["x509_key_path"] = "i/am/a/file/that/doesnt/exist"
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ func TestBuilderPrepare_X509KeyPath(t *testing.T) {
|
|||
defer tf.Close()
|
||||
|
||||
config["x509_key_path"] = tf.Name()
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ func TestBuilderPrepare_X509UploadPath(t *testing.T) {
|
|||
defer tempfile.Close()
|
||||
|
||||
config["x509_upload_path"] = ""
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
|
|
@ -237,7 +237,7 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string
|
|||
azureClient.GalleryImagesClient.RequestInspector = withInspection(maxlen)
|
||||
azureClient.GalleryImagesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient))
|
||||
azureClient.GalleryImagesClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.GalleryImagesClient.UserAgent)
|
||||
azureClient.GalleryImageVersionsClient.Client.PollingDuration = PollingDuration
|
||||
azureClient.GalleryImagesClient.Client.PollingDuration = PollingDuration
|
||||
|
||||
keyVaultURL, err := url.Parse(cloud.KeyVaultEndpoint)
|
||||
if err != nil {
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/Azure/azure-sdk-for-go/storage"
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
packerAzureCommon "github.com/hashicorp/packer/builder/azure/common"
|
||||
"github.com/hashicorp/packer/builder/azure/common/constants"
|
||||
"github.com/hashicorp/packer/builder/azure/common/lin"
|
||||
|
@ -24,7 +25,7 @@ import (
|
|||
)
|
||||
|
||||
type Builder struct {
|
||||
config *Config
|
||||
config Config
|
||||
stateBag multistep.StateBag
|
||||
runner multistep.Runner
|
||||
}
|
||||
|
@ -34,20 +35,20 @@ const (
|
|||
DefaultSecretName = "packerKeyVaultSecret"
|
||||
)
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
c, warnings, errs := newConfig(raws...)
|
||||
if errs != nil {
|
||||
return warnings, errs
|
||||
}
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
b.config = c
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
warnings, errs := b.config.Prepare(raws...)
|
||||
if errs != nil {
|
||||
return nil, warnings, errs
|
||||
}
|
||||
|
||||
b.stateBag = new(multistep.BasicStateBag)
|
||||
b.configureStateBag(b.stateBag)
|
||||
b.setTemplateParameters(b.stateBag)
|
||||
b.setImageParameters(b.stateBag)
|
||||
|
||||
return warnings, errs
|
||||
return nil, warnings, errs
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||
|
@ -64,7 +65,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
}
|
||||
|
||||
log.Print(":: Configuration")
|
||||
packerAzureCommon.DumpConfig(b.config, func(s string) { log.Print(s) })
|
||||
packerAzureCommon.DumpConfig(&b.config, func(s string) { log.Print(s) })
|
||||
|
||||
b.stateBag.Put("hook", hook)
|
||||
b.stateBag.Put(constants.Ui, ui)
|
||||
|
@ -90,7 +91,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
}
|
||||
|
||||
resolver := newResourceResolver(azureClient)
|
||||
if err := resolver.Resolve(b.config); err != nil {
|
||||
if err := resolver.Resolve(&b.config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if b.config.ClientConfig.ObjectID == "" {
|
||||
|
@ -197,8 +198,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
if b.config.OSType == constants.Target_Linux {
|
||||
steps = []multistep.Step{
|
||||
NewStepCreateResourceGroup(azureClient, ui),
|
||||
NewStepValidateTemplate(azureClient, ui, b.config, GetVirtualMachineDeployment),
|
||||
NewStepDeployTemplate(azureClient, ui, b.config, deploymentName, GetVirtualMachineDeployment),
|
||||
NewStepValidateTemplate(azureClient, ui, &b.config, GetVirtualMachineDeployment),
|
||||
NewStepDeployTemplate(azureClient, ui, &b.config, deploymentName, GetVirtualMachineDeployment),
|
||||
NewStepGetIPAddress(azureClient, ui, endpointConnectType),
|
||||
&communicator.StepConnectSSH{
|
||||
Config: &b.config.Comm,
|
||||
|
@ -212,10 +213,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
NewStepGetOSDisk(azureClient, ui),
|
||||
NewStepGetAdditionalDisks(azureClient, ui),
|
||||
NewStepPowerOffCompute(azureClient, ui),
|
||||
NewStepSnapshotOSDisk(azureClient, ui, b.config),
|
||||
NewStepSnapshotDataDisks(azureClient, ui, b.config),
|
||||
NewStepSnapshotOSDisk(azureClient, ui, &b.config),
|
||||
NewStepSnapshotDataDisks(azureClient, ui, &b.config),
|
||||
NewStepCaptureImage(azureClient, ui),
|
||||
NewStepPublishToSharedImageGallery(azureClient, ui, b.config),
|
||||
NewStepPublishToSharedImageGallery(azureClient, ui, &b.config),
|
||||
NewStepDeleteResourceGroup(azureClient, ui),
|
||||
NewStepDeleteOSDisk(azureClient, ui),
|
||||
NewStepDeleteAdditionalDisks(azureClient, ui),
|
||||
|
@ -224,17 +225,13 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
keyVaultDeploymentName := b.stateBag.Get(constants.ArmKeyVaultDeploymentName).(string)
|
||||
steps = []multistep.Step{
|
||||
NewStepCreateResourceGroup(azureClient, ui),
|
||||
NewStepValidateTemplate(azureClient, ui, b.config, GetKeyVaultDeployment),
|
||||
NewStepDeployTemplate(azureClient, ui, b.config, keyVaultDeploymentName, GetKeyVaultDeployment),
|
||||
NewStepValidateTemplate(azureClient, ui, &b.config, GetKeyVaultDeployment),
|
||||
NewStepDeployTemplate(azureClient, ui, &b.config, keyVaultDeploymentName, GetKeyVaultDeployment),
|
||||
NewStepGetCertificate(azureClient, ui),
|
||||
NewStepSetCertificate(b.config, ui),
|
||||
NewStepValidateTemplate(azureClient, ui, b.config, GetVirtualMachineDeployment),
|
||||
NewStepDeployTemplate(azureClient, ui, b.config, deploymentName, GetVirtualMachineDeployment),
|
||||
NewStepSetCertificate(&b.config, ui),
|
||||
NewStepValidateTemplate(azureClient, ui, &b.config, GetVirtualMachineDeployment),
|
||||
NewStepDeployTemplate(azureClient, ui, &b.config, deploymentName, GetVirtualMachineDeployment),
|
||||
NewStepGetIPAddress(azureClient, ui, endpointConnectType),
|
||||
&StepSaveWinRMPassword{
|
||||
Password: b.config.tmpAdminPassword,
|
||||
BuildName: b.config.PackerBuildName,
|
||||
},
|
||||
&communicator.StepConnectWinRM{
|
||||
Config: &b.config.Comm,
|
||||
Host: func(stateBag multistep.StateBag) (string, error) {
|
||||
|
@ -251,10 +248,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
NewStepGetOSDisk(azureClient, ui),
|
||||
NewStepGetAdditionalDisks(azureClient, ui),
|
||||
NewStepPowerOffCompute(azureClient, ui),
|
||||
NewStepSnapshotOSDisk(azureClient, ui, b.config),
|
||||
NewStepSnapshotDataDisks(azureClient, ui, b.config),
|
||||
NewStepSnapshotOSDisk(azureClient, ui, &b.config),
|
||||
NewStepSnapshotDataDisks(azureClient, ui, &b.config),
|
||||
NewStepCaptureImage(azureClient, ui),
|
||||
NewStepPublishToSharedImageGallery(azureClient, ui, b.config),
|
||||
NewStepPublishToSharedImageGallery(azureClient, ui, &b.config),
|
||||
NewStepDeleteResourceGroup(azureClient, ui),
|
||||
NewStepDeleteOSDisk(azureClient, ui),
|
||||
NewStepDeleteAdditionalDisks(azureClient, ui),
|
||||
|
@ -398,6 +395,9 @@ func (b *Builder) configureStateBag(stateBag multistep.StateBag) {
|
|||
stateBag.Put(constants.ArmManagedImageSharedGalleryImageName, b.config.SharedGalleryDestination.SigDestinationImageName)
|
||||
stateBag.Put(constants.ArmManagedImageSharedGalleryImageVersion, b.config.SharedGalleryDestination.SigDestinationImageVersion)
|
||||
stateBag.Put(constants.ArmManagedImageSubscription, b.config.ClientConfig.SubscriptionID)
|
||||
stateBag.Put(constants.ArmManagedImageSharedGalleryImageVersionEndOfLifeDate, b.config.SharedGalleryImageVersionEndOfLifeDate)
|
||||
stateBag.Put(constants.ArmManagedImageSharedGalleryImageVersionReplicaCount, b.config.SharedGalleryImageVersionReplicaCount)
|
||||
stateBag.Put(constants.ArmManagedImageSharedGalleryImageVersionExcludeFromLatest, b.config.SharedGalleryImageVersionExcludeFromLatest)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
)
|
||||
|
||||
func TestStateBagShouldBePopulatedExpectedValues(t *testing.T) {
|
||||
var testSubject = &Builder{}
|
||||
_, err := testSubject.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
var testSubject Builder
|
||||
_, _, err := testSubject.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatalf("failed to prepare: %s", err)
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import (
|
|||
"github.com/hashicorp/packer/builder/azure/common/constants"
|
||||
"github.com/hashicorp/packer/builder/azure/pkcs12"
|
||||
"github.com/hashicorp/packer/common"
|
||||
commonhelper "github.com/hashicorp/packer/helper/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/config"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
@ -120,8 +119,6 @@ type Config struct {
|
|||
//
|
||||
// Following is an example.
|
||||
//
|
||||
// <!-- -->
|
||||
//
|
||||
// "shared_image_gallery_destination": {
|
||||
// "resource_group": "ResourceGroup",
|
||||
// "gallery_name": "GalleryName",
|
||||
|
@ -140,6 +137,16 @@ type Config struct {
|
|||
// its default of "60m" (valid time units include `s` for seconds, `m` for
|
||||
// minutes, and `h` for hours.)
|
||||
SharedGalleryTimeout time.Duration `mapstructure:"shared_image_gallery_timeout"`
|
||||
// The end of life date (2006-01-02T15:04:05.99Z) of the gallery Image Version. This property
|
||||
// can be used for decommissioning purposes.
|
||||
SharedGalleryImageVersionEndOfLifeDate string `mapstructure:"shared_gallery_image_version_end_of_life_date" required:"false"`
|
||||
// The number of replicas of the Image Version to be created per region. This
|
||||
// property would take effect for a region when regionalReplicaCount is not specified.
|
||||
// Replica count must be between 1 and 10.
|
||||
SharedGalleryImageVersionReplicaCount int32 `mapstructure:"shared_image_gallery_replica_count" required:"false"`
|
||||
// If set to true, Virtual Machines deployed from the latest version of the
|
||||
// Image Definition won't use this Image Version.
|
||||
SharedGalleryImageVersionExcludeFromLatest bool `mapstructure:"shared_gallery_image_version_exclude_from_latest" required:"false"`
|
||||
// PublisherName for your base image. See
|
||||
// [documentation](https://azure.microsoft.com/en-us/documentation/articles/resource-groups-vm-searching/)
|
||||
// for details.
|
||||
|
@ -495,58 +502,57 @@ func (c *Config) createCertificate() (string, error) {
|
|||
return base64.StdEncoding.EncodeToString(bytes), nil
|
||||
}
|
||||
|
||||
func newConfig(raws ...interface{}) (*Config, []string, error) {
|
||||
var c Config
|
||||
func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
||||
c.ctx.Funcs = azcommon.TemplateFuncs
|
||||
err := config.Decode(&c, &config.DecodeOpts{
|
||||
err := config.Decode(c, &config.DecodeOpts{
|
||||
Interpolate: true,
|
||||
InterpolateContext: &c.ctx,
|
||||
}, raws...)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
provideDefaultValues(&c)
|
||||
setRuntimeValues(&c)
|
||||
setUserNamePassword(&c)
|
||||
provideDefaultValues(c)
|
||||
setRuntimeValues(c)
|
||||
setUserNamePassword(c)
|
||||
err = c.ClientConfig.SetDefaultValues()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = setCustomData(&c)
|
||||
err = setCustomData(c)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// NOTE: if the user did not specify a communicator, then default to both
|
||||
// SSH and WinRM. This is for backwards compatibility because the code did
|
||||
// not specifically force the user to set a communicator.
|
||||
if c.Comm.Type == "" || strings.EqualFold(c.Comm.Type, "ssh") {
|
||||
err = setSshValues(&c)
|
||||
err = setSshValues(c)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if c.Comm.Type == "" || strings.EqualFold(c.Comm.Type, "winrm") {
|
||||
err = setWinRMCertificate(&c)
|
||||
err = setWinRMCertificate(c)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var errs *packer.MultiError
|
||||
errs = packer.MultiErrorAppend(errs, c.Comm.Prepare(&c.ctx)...)
|
||||
|
||||
assertRequiredParametersSet(&c, errs)
|
||||
assertTagProperties(&c, errs)
|
||||
assertRequiredParametersSet(c, errs)
|
||||
assertTagProperties(c, errs)
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, nil, errs
|
||||
return nil, errs
|
||||
}
|
||||
|
||||
return &c, nil, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func setSshValues(c *Config) error {
|
||||
|
@ -601,7 +607,6 @@ func setRuntimeValues(c *Config) {
|
|||
|
||||
c.tmpAdminPassword = tempName.AdminPassword
|
||||
// store so that we can access this later during provisioning
|
||||
commonhelper.SetSharedState("winrm_password", c.tmpAdminPassword, c.PackerConfig.PackerBuildName)
|
||||
packer.LogSecretFilter.Set(c.tmpAdminPassword)
|
||||
|
||||
c.tmpCertificatePassword = tempName.CertificatePassword
|
||||
|
|
|
@ -9,138 +9,147 @@ import (
|
|||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatConfig struct {
|
||||
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
|
||||
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
|
||||
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
|
||||
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
|
||||
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
|
||||
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
|
||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
|
||||
CloudEnvironmentName *string `mapstructure:"cloud_environment_name" required:"false" cty:"cloud_environment_name"`
|
||||
ClientID *string `mapstructure:"client_id" cty:"client_id"`
|
||||
ClientSecret *string `mapstructure:"client_secret" cty:"client_secret"`
|
||||
ClientCertPath *string `mapstructure:"client_cert_path" cty:"client_cert_path"`
|
||||
ClientJWT *string `mapstructure:"client_jwt" cty:"client_jwt"`
|
||||
ObjectID *string `mapstructure:"object_id" cty:"object_id"`
|
||||
TenantID *string `mapstructure:"tenant_id" required:"false" cty:"tenant_id"`
|
||||
SubscriptionID *string `mapstructure:"subscription_id" cty:"subscription_id"`
|
||||
CaptureNamePrefix *string `mapstructure:"capture_name_prefix" cty:"capture_name_prefix"`
|
||||
CaptureContainerName *string `mapstructure:"capture_container_name" cty:"capture_container_name"`
|
||||
SharedGallery *FlatSharedImageGallery `mapstructure:"shared_image_gallery" required:"false" cty:"shared_image_gallery"`
|
||||
SharedGalleryDestination *FlatSharedImageGalleryDestination `mapstructure:"shared_image_gallery_destination" cty:"shared_image_gallery_destination"`
|
||||
SharedGalleryTimeout *string `mapstructure:"shared_image_gallery_timeout" cty:"shared_image_gallery_timeout"`
|
||||
ImagePublisher *string `mapstructure:"image_publisher" required:"true" cty:"image_publisher"`
|
||||
ImageOffer *string `mapstructure:"image_offer" required:"true" cty:"image_offer"`
|
||||
ImageSku *string `mapstructure:"image_sku" required:"true" cty:"image_sku"`
|
||||
ImageVersion *string `mapstructure:"image_version" required:"false" cty:"image_version"`
|
||||
ImageUrl *string `mapstructure:"image_url" required:"false" cty:"image_url"`
|
||||
CustomManagedImageResourceGroupName *string `mapstructure:"custom_managed_image_resource_group_name" required:"false" cty:"custom_managed_image_resource_group_name"`
|
||||
CustomManagedImageName *string `mapstructure:"custom_managed_image_name" required:"false" cty:"custom_managed_image_name"`
|
||||
Location *string `mapstructure:"location" cty:"location"`
|
||||
VMSize *string `mapstructure:"vm_size" required:"false" cty:"vm_size"`
|
||||
ManagedImageResourceGroupName *string `mapstructure:"managed_image_resource_group_name" cty:"managed_image_resource_group_name"`
|
||||
ManagedImageName *string `mapstructure:"managed_image_name" cty:"managed_image_name"`
|
||||
ManagedImageStorageAccountType *string `mapstructure:"managed_image_storage_account_type" required:"false" cty:"managed_image_storage_account_type"`
|
||||
ManagedImageOSDiskSnapshotName *string `mapstructure:"managed_image_os_disk_snapshot_name" required:"false" cty:"managed_image_os_disk_snapshot_name"`
|
||||
ManagedImageDataDiskSnapshotPrefix *string `mapstructure:"managed_image_data_disk_snapshot_prefix" required:"false" cty:"managed_image_data_disk_snapshot_prefix"`
|
||||
ManagedImageZoneResilient *bool `mapstructure:"managed_image_zone_resilient" required:"false" cty:"managed_image_zone_resilient"`
|
||||
AzureTags map[string]*string `mapstructure:"azure_tags" required:"false" cty:"azure_tags"`
|
||||
ResourceGroupName *string `mapstructure:"resource_group_name" cty:"resource_group_name"`
|
||||
StorageAccount *string `mapstructure:"storage_account" cty:"storage_account"`
|
||||
TempComputeName *string `mapstructure:"temp_compute_name" required:"false" cty:"temp_compute_name"`
|
||||
TempResourceGroupName *string `mapstructure:"temp_resource_group_name" cty:"temp_resource_group_name"`
|
||||
BuildResourceGroupName *string `mapstructure:"build_resource_group_name" cty:"build_resource_group_name"`
|
||||
PrivateVirtualNetworkWithPublicIp *bool `mapstructure:"private_virtual_network_with_public_ip" required:"false" cty:"private_virtual_network_with_public_ip"`
|
||||
VirtualNetworkName *string `mapstructure:"virtual_network_name" required:"false" cty:"virtual_network_name"`
|
||||
VirtualNetworkSubnetName *string `mapstructure:"virtual_network_subnet_name" required:"false" cty:"virtual_network_subnet_name"`
|
||||
VirtualNetworkResourceGroupName *string `mapstructure:"virtual_network_resource_group_name" required:"false" cty:"virtual_network_resource_group_name"`
|
||||
CustomDataFile *string `mapstructure:"custom_data_file" required:"false" cty:"custom_data_file"`
|
||||
PlanInfo *FlatPlanInformation `mapstructure:"plan_info" required:"false" cty:"plan_info"`
|
||||
PollingDurationTimeout *string `mapstructure:"polling_duration_timeout" required:"false" cty:"polling_duration_timeout"`
|
||||
OSType *string `mapstructure:"os_type" required:"false" cty:"os_type"`
|
||||
OSDiskSizeGB *int32 `mapstructure:"os_disk_size_gb" required:"false" cty:"os_disk_size_gb"`
|
||||
AdditionalDiskSize []int32 `mapstructure:"disk_additional_size" required:"false" cty:"disk_additional_size"`
|
||||
DiskCachingType *string `mapstructure:"disk_caching_type" required:"false" cty:"disk_caching_type"`
|
||||
AllowedInboundIpAddresses []string `mapstructure:"allowed_inbound_ip_addresses" cty:"allowed_inbound_ip_addresses"`
|
||||
UserName *string `cty:"user_name"`
|
||||
Password *string `cty:"password"`
|
||||
Type *string `mapstructure:"communicator" cty:"communicator"`
|
||||
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"`
|
||||
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host"`
|
||||
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port"`
|
||||
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username"`
|
||||
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password"`
|
||||
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" cty:"ssh_keypair_name"`
|
||||
SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" cty:"temporary_key_pair_name"`
|
||||
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys"`
|
||||
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" cty:"ssh_private_key_file"`
|
||||
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty"`
|
||||
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout"`
|
||||
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" cty:"ssh_agent_auth"`
|
||||
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding"`
|
||||
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts"`
|
||||
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host"`
|
||||
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port"`
|
||||
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"`
|
||||
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"`
|
||||
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"`
|
||||
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"`
|
||||
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"`
|
||||
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"`
|
||||
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port"`
|
||||
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username"`
|
||||
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password"`
|
||||
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval"`
|
||||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port"`
|
||||
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout"`
|
||||
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl"`
|
||||
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
|
||||
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
|
||||
AsyncResourceGroupDelete *bool `mapstructure:"async_resourcegroup_delete" required:"false" cty:"async_resourcegroup_delete"`
|
||||
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
|
||||
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
|
||||
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
|
||||
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
|
||||
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
|
||||
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
|
||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
|
||||
CloudEnvironmentName *string `mapstructure:"cloud_environment_name" required:"false" cty:"cloud_environment_name"`
|
||||
ClientID *string `mapstructure:"client_id" cty:"client_id"`
|
||||
ClientSecret *string `mapstructure:"client_secret" cty:"client_secret"`
|
||||
ClientCertPath *string `mapstructure:"client_cert_path" cty:"client_cert_path"`
|
||||
ClientJWT *string `mapstructure:"client_jwt" cty:"client_jwt"`
|
||||
ObjectID *string `mapstructure:"object_id" cty:"object_id"`
|
||||
TenantID *string `mapstructure:"tenant_id" required:"false" cty:"tenant_id"`
|
||||
SubscriptionID *string `mapstructure:"subscription_id" cty:"subscription_id"`
|
||||
CaptureNamePrefix *string `mapstructure:"capture_name_prefix" cty:"capture_name_prefix"`
|
||||
CaptureContainerName *string `mapstructure:"capture_container_name" cty:"capture_container_name"`
|
||||
SharedGallery *FlatSharedImageGallery `mapstructure:"shared_image_gallery" required:"false" cty:"shared_image_gallery"`
|
||||
SharedGalleryDestination *FlatSharedImageGalleryDestination `mapstructure:"shared_image_gallery_destination" cty:"shared_image_gallery_destination"`
|
||||
SharedGalleryTimeout *string `mapstructure:"shared_image_gallery_timeout" cty:"shared_image_gallery_timeout"`
|
||||
SharedGalleryImageVersionEndOfLifeDate *string `mapstructure:"shared_gallery_image_version_end_of_life_date" required:"false" cty:"shared_gallery_image_version_end_of_life_date"`
|
||||
SharedGalleryImageVersionReplicaCount *int32 `mapstructure:"shared_image_gallery_replica_count" required:"false" cty:"shared_image_gallery_replica_count"`
|
||||
SharedGalleryImageVersionExcludeFromLatest *bool `mapstructure:"shared_gallery_image_version_exclude_from_latest" required:"false" cty:"shared_gallery_image_version_exclude_from_latest"`
|
||||
ImagePublisher *string `mapstructure:"image_publisher" required:"true" cty:"image_publisher"`
|
||||
ImageOffer *string `mapstructure:"image_offer" required:"true" cty:"image_offer"`
|
||||
ImageSku *string `mapstructure:"image_sku" required:"true" cty:"image_sku"`
|
||||
ImageVersion *string `mapstructure:"image_version" required:"false" cty:"image_version"`
|
||||
ImageUrl *string `mapstructure:"image_url" required:"false" cty:"image_url"`
|
||||
CustomManagedImageResourceGroupName *string `mapstructure:"custom_managed_image_resource_group_name" required:"false" cty:"custom_managed_image_resource_group_name"`
|
||||
CustomManagedImageName *string `mapstructure:"custom_managed_image_name" required:"false" cty:"custom_managed_image_name"`
|
||||
Location *string `mapstructure:"location" cty:"location"`
|
||||
VMSize *string `mapstructure:"vm_size" required:"false" cty:"vm_size"`
|
||||
ManagedImageResourceGroupName *string `mapstructure:"managed_image_resource_group_name" cty:"managed_image_resource_group_name"`
|
||||
ManagedImageName *string `mapstructure:"managed_image_name" cty:"managed_image_name"`
|
||||
ManagedImageStorageAccountType *string `mapstructure:"managed_image_storage_account_type" required:"false" cty:"managed_image_storage_account_type"`
|
||||
ManagedImageOSDiskSnapshotName *string `mapstructure:"managed_image_os_disk_snapshot_name" required:"false" cty:"managed_image_os_disk_snapshot_name"`
|
||||
ManagedImageDataDiskSnapshotPrefix *string `mapstructure:"managed_image_data_disk_snapshot_prefix" required:"false" cty:"managed_image_data_disk_snapshot_prefix"`
|
||||
ManagedImageZoneResilient *bool `mapstructure:"managed_image_zone_resilient" required:"false" cty:"managed_image_zone_resilient"`
|
||||
AzureTags map[string]*string `mapstructure:"azure_tags" required:"false" cty:"azure_tags"`
|
||||
ResourceGroupName *string `mapstructure:"resource_group_name" cty:"resource_group_name"`
|
||||
StorageAccount *string `mapstructure:"storage_account" cty:"storage_account"`
|
||||
TempComputeName *string `mapstructure:"temp_compute_name" required:"false" cty:"temp_compute_name"`
|
||||
TempResourceGroupName *string `mapstructure:"temp_resource_group_name" cty:"temp_resource_group_name"`
|
||||
BuildResourceGroupName *string `mapstructure:"build_resource_group_name" cty:"build_resource_group_name"`
|
||||
PrivateVirtualNetworkWithPublicIp *bool `mapstructure:"private_virtual_network_with_public_ip" required:"false" cty:"private_virtual_network_with_public_ip"`
|
||||
VirtualNetworkName *string `mapstructure:"virtual_network_name" required:"false" cty:"virtual_network_name"`
|
||||
VirtualNetworkSubnetName *string `mapstructure:"virtual_network_subnet_name" required:"false" cty:"virtual_network_subnet_name"`
|
||||
VirtualNetworkResourceGroupName *string `mapstructure:"virtual_network_resource_group_name" required:"false" cty:"virtual_network_resource_group_name"`
|
||||
CustomDataFile *string `mapstructure:"custom_data_file" required:"false" cty:"custom_data_file"`
|
||||
PlanInfo *FlatPlanInformation `mapstructure:"plan_info" required:"false" cty:"plan_info"`
|
||||
PollingDurationTimeout *string `mapstructure:"polling_duration_timeout" required:"false" cty:"polling_duration_timeout"`
|
||||
OSType *string `mapstructure:"os_type" required:"false" cty:"os_type"`
|
||||
OSDiskSizeGB *int32 `mapstructure:"os_disk_size_gb" required:"false" cty:"os_disk_size_gb"`
|
||||
AdditionalDiskSize []int32 `mapstructure:"disk_additional_size" required:"false" cty:"disk_additional_size"`
|
||||
DiskCachingType *string `mapstructure:"disk_caching_type" required:"false" cty:"disk_caching_type"`
|
||||
AllowedInboundIpAddresses []string `mapstructure:"allowed_inbound_ip_addresses" cty:"allowed_inbound_ip_addresses"`
|
||||
UserName *string `cty:"user_name"`
|
||||
Password *string `cty:"password"`
|
||||
Type *string `mapstructure:"communicator" cty:"communicator"`
|
||||
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"`
|
||||
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host"`
|
||||
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port"`
|
||||
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username"`
|
||||
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password"`
|
||||
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" cty:"ssh_keypair_name"`
|
||||
SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" cty:"temporary_key_pair_name"`
|
||||
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys"`
|
||||
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" cty:"ssh_private_key_file"`
|
||||
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty"`
|
||||
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout"`
|
||||
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" cty:"ssh_agent_auth"`
|
||||
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding"`
|
||||
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts"`
|
||||
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host"`
|
||||
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port"`
|
||||
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"`
|
||||
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"`
|
||||
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"`
|
||||
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"`
|
||||
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"`
|
||||
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"`
|
||||
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port"`
|
||||
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username"`
|
||||
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password"`
|
||||
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval"`
|
||||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port"`
|
||||
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout"`
|
||||
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl"`
|
||||
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
|
||||
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
|
||||
AsyncResourceGroupDelete *bool `mapstructure:"async_resourcegroup_delete" required:"false" cty:"async_resourcegroup_delete"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{} { return new(FlatConfig) }
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatConfig.
|
||||
// This spec is used by HCL to read the fields of FlatConfig.
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
|
||||
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
|
||||
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
|
||||
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
|
||||
"packer_user_variables": &hcldec.BlockAttrsSpec{TypeName: "packer_user_variables", ElementType: cty.String, Required: false},
|
||||
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
|
||||
"cloud_environment_name": &hcldec.AttrSpec{Name: "cloud_environment_name", Type: cty.String, Required: false},
|
||||
"client_id": &hcldec.AttrSpec{Name: "client_id", Type: cty.String, Required: false},
|
||||
"client_secret": &hcldec.AttrSpec{Name: "client_secret", Type: cty.String, Required: false},
|
||||
"client_cert_path": &hcldec.AttrSpec{Name: "client_cert_path", Type: cty.String, Required: false},
|
||||
"client_jwt": &hcldec.AttrSpec{Name: "client_jwt", Type: cty.String, Required: false},
|
||||
"object_id": &hcldec.AttrSpec{Name: "object_id", Type: cty.String, Required: false},
|
||||
"tenant_id": &hcldec.AttrSpec{Name: "tenant_id", Type: cty.String, Required: false},
|
||||
"subscription_id": &hcldec.AttrSpec{Name: "subscription_id", Type: cty.String, Required: false},
|
||||
"capture_name_prefix": &hcldec.AttrSpec{Name: "capture_name_prefix", Type: cty.String, Required: false},
|
||||
"capture_container_name": &hcldec.AttrSpec{Name: "capture_container_name", Type: cty.String, Required: false},
|
||||
"shared_image_gallery": &hcldec.BlockSpec{TypeName: "shared_image_gallery", Nested: hcldec.ObjectSpec((*FlatSharedImageGallery)(nil).HCL2Spec())},
|
||||
"shared_image_gallery_destination": &hcldec.BlockSpec{TypeName: "shared_image_gallery_destination", Nested: hcldec.ObjectSpec((*FlatSharedImageGalleryDestination)(nil).HCL2Spec())},
|
||||
"shared_image_gallery_timeout": &hcldec.AttrSpec{Name: "shared_image_gallery_timeout", Type: cty.String, Required: false},
|
||||
"image_publisher": &hcldec.AttrSpec{Name: "image_publisher", Type: cty.String, Required: false},
|
||||
"image_offer": &hcldec.AttrSpec{Name: "image_offer", Type: cty.String, Required: false},
|
||||
"image_sku": &hcldec.AttrSpec{Name: "image_sku", Type: cty.String, Required: false},
|
||||
"image_version": &hcldec.AttrSpec{Name: "image_version", Type: cty.String, Required: false},
|
||||
"image_url": &hcldec.AttrSpec{Name: "image_url", Type: cty.String, Required: false},
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
|
||||
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
|
||||
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
|
||||
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
|
||||
"packer_user_variables": &hcldec.BlockAttrsSpec{TypeName: "packer_user_variables", ElementType: cty.String, Required: false},
|
||||
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
|
||||
"cloud_environment_name": &hcldec.AttrSpec{Name: "cloud_environment_name", Type: cty.String, Required: false},
|
||||
"client_id": &hcldec.AttrSpec{Name: "client_id", Type: cty.String, Required: false},
|
||||
"client_secret": &hcldec.AttrSpec{Name: "client_secret", Type: cty.String, Required: false},
|
||||
"client_cert_path": &hcldec.AttrSpec{Name: "client_cert_path", Type: cty.String, Required: false},
|
||||
"client_jwt": &hcldec.AttrSpec{Name: "client_jwt", Type: cty.String, Required: false},
|
||||
"object_id": &hcldec.AttrSpec{Name: "object_id", Type: cty.String, Required: false},
|
||||
"tenant_id": &hcldec.AttrSpec{Name: "tenant_id", Type: cty.String, Required: false},
|
||||
"subscription_id": &hcldec.AttrSpec{Name: "subscription_id", Type: cty.String, Required: false},
|
||||
"capture_name_prefix": &hcldec.AttrSpec{Name: "capture_name_prefix", Type: cty.String, Required: false},
|
||||
"capture_container_name": &hcldec.AttrSpec{Name: "capture_container_name", Type: cty.String, Required: false},
|
||||
"shared_image_gallery": &hcldec.BlockSpec{TypeName: "shared_image_gallery", Nested: hcldec.ObjectSpec((*FlatSharedImageGallery)(nil).HCL2Spec())},
|
||||
"shared_image_gallery_destination": &hcldec.BlockSpec{TypeName: "shared_image_gallery_destination", Nested: hcldec.ObjectSpec((*FlatSharedImageGalleryDestination)(nil).HCL2Spec())},
|
||||
"shared_image_gallery_timeout": &hcldec.AttrSpec{Name: "shared_image_gallery_timeout", Type: cty.String, Required: false},
|
||||
"shared_gallery_image_version_end_of_life_date": &hcldec.AttrSpec{Name: "shared_gallery_image_version_end_of_life_date", Type: cty.String, Required: false},
|
||||
"shared_image_gallery_replica_count": &hcldec.AttrSpec{Name: "shared_image_gallery_replica_count", Type: cty.Number, Required: false},
|
||||
"shared_gallery_image_version_exclude_from_latest": &hcldec.AttrSpec{Name: "shared_gallery_image_version_exclude_from_latest", Type: cty.Bool, Required: false},
|
||||
"image_publisher": &hcldec.AttrSpec{Name: "image_publisher", Type: cty.String, Required: false},
|
||||
"image_offer": &hcldec.AttrSpec{Name: "image_offer", Type: cty.String, Required: false},
|
||||
"image_sku": &hcldec.AttrSpec{Name: "image_sku", Type: cty.String, Required: false},
|
||||
"image_version": &hcldec.AttrSpec{Name: "image_version", Type: cty.String, Required: false},
|
||||
"image_url": &hcldec.AttrSpec{Name: "image_url", Type: cty.String, Required: false},
|
||||
"custom_managed_image_resource_group_name": &hcldec.AttrSpec{Name: "custom_managed_image_resource_group_name", Type: cty.String, Required: false},
|
||||
"custom_managed_image_name": &hcldec.AttrSpec{Name: "custom_managed_image_name", Type: cty.String, Required: false},
|
||||
"location": &hcldec.AttrSpec{Name: "location", Type: cty.String, Required: false},
|
||||
|
@ -228,10 +237,13 @@ type FlatPlanInformation struct {
|
|||
// FlatMapstructure returns a new FlatPlanInformation.
|
||||
// FlatPlanInformation is an auto-generated flat version of PlanInformation.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*PlanInformation) FlatMapstructure() interface{} { return new(FlatPlanInformation) }
|
||||
func (*PlanInformation) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatPlanInformation)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatPlanInformation.
|
||||
// This spec is used by HCL to read the fields of FlatPlanInformation.
|
||||
// HCL2Spec returns the hcl spec of a PlanInformation.
|
||||
// This spec is used by HCL to read the fields of PlanInformation.
|
||||
// The decoded values from this spec will then be applied to a FlatPlanInformation.
|
||||
func (*FlatPlanInformation) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"plan_name": &hcldec.AttrSpec{Name: "plan_name", Type: cty.String, Required: false},
|
||||
|
@ -255,10 +267,13 @@ type FlatSharedImageGallery struct {
|
|||
// FlatMapstructure returns a new FlatSharedImageGallery.
|
||||
// FlatSharedImageGallery is an auto-generated flat version of SharedImageGallery.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*SharedImageGallery) FlatMapstructure() interface{} { return new(FlatSharedImageGallery) }
|
||||
func (*SharedImageGallery) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatSharedImageGallery)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatSharedImageGallery.
|
||||
// This spec is used by HCL to read the fields of FlatSharedImageGallery.
|
||||
// HCL2Spec returns the hcl spec of a SharedImageGallery.
|
||||
// This spec is used by HCL to read the fields of SharedImageGallery.
|
||||
// The decoded values from this spec will then be applied to a FlatSharedImageGallery.
|
||||
func (*FlatSharedImageGallery) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"subscription": &hcldec.AttrSpec{Name: "subscription", Type: cty.String, Required: false},
|
||||
|
@ -283,12 +298,13 @@ type FlatSharedImageGalleryDestination struct {
|
|||
// FlatMapstructure returns a new FlatSharedImageGalleryDestination.
|
||||
// FlatSharedImageGalleryDestination is an auto-generated flat version of SharedImageGalleryDestination.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*SharedImageGalleryDestination) FlatMapstructure() interface{} {
|
||||
func (*SharedImageGalleryDestination) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatSharedImageGalleryDestination)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatSharedImageGalleryDestination.
|
||||
// This spec is used by HCL to read the fields of FlatSharedImageGalleryDestination.
|
||||
// HCL2Spec returns the hcl spec of a SharedImageGalleryDestination.
|
||||
// This spec is used by HCL to read the fields of SharedImageGalleryDestination.
|
||||
// The decoded values from this spec will then be applied to a FlatSharedImageGalleryDestination.
|
||||
func (*FlatSharedImageGalleryDestination) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"resource_group": &hcldec.AttrSpec{Name: "resource_group", Type: cty.String, Required: false},
|
||||
|
|
|
@ -26,7 +26,8 @@ var requiredConfigValues = []string{
|
|||
}
|
||||
|
||||
func TestConfigShouldProvideReasonableDefaultValues(t *testing.T) {
|
||||
c, _, err := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
|
||||
if err != nil {
|
||||
t.Error("Expected configuration creation to succeed, but it failed!\n")
|
||||
|
@ -63,7 +64,8 @@ func TestConfigShouldBeAbleToOverrideDefaultedValues(t *testing.T) {
|
|||
builderValues["managed_image_storage_account_type"] = "Premium_LRS"
|
||||
builderValues["disk_caching_type"] = "None"
|
||||
|
||||
c, _, err := newConfig(builderValues, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(builderValues, getPackerConfiguration())
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("newConfig failed: %s", err)
|
||||
|
@ -99,7 +101,8 @@ func TestConfigShouldBeAbleToOverrideDefaultedValues(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfigShouldDefaultVMSizeToStandardA1(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
|
||||
if c.VMSize != "Standard_A1" {
|
||||
t.Errorf("Expected 'VMSize' to default to 'Standard_A1', but got '%s'.", c.VMSize)
|
||||
|
@ -107,7 +110,8 @@ func TestConfigShouldDefaultVMSizeToStandardA1(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfigShouldDefaultImageVersionToLatest(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
|
||||
if c.ImageVersion != "latest" {
|
||||
t.Errorf("Expected 'ImageVersion' to default to 'latest', but got '%s'.", c.ImageVersion)
|
||||
|
@ -127,7 +131,8 @@ func TestConfigShouldNotDefaultImageVersionIfCustomImage(t *testing.T) {
|
|||
"communicator": "none",
|
||||
}
|
||||
|
||||
c, _, _ := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(config, getPackerConfiguration())
|
||||
if c.ImageVersion != "" {
|
||||
t.Errorf("Expected 'ImageVersion' to empty, but got '%s'.", c.ImageVersion)
|
||||
}
|
||||
|
@ -153,7 +158,8 @@ func TestConfigShouldNormalizeOSTypeCase(t *testing.T) {
|
|||
for k, v := range os_types {
|
||||
for _, os_type := range v {
|
||||
config["os_type"] = os_type
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatalf("Expected config to accept the value %q, but it did not", os_type)
|
||||
}
|
||||
|
@ -167,7 +173,8 @@ func TestConfigShouldNormalizeOSTypeCase(t *testing.T) {
|
|||
bad_os_types := []string{"", "does-not-exist"}
|
||||
for _, os_type := range bad_os_types {
|
||||
config["os_type"] = os_type
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatalf("Expected config to not accept the value %q, but it did", os_type)
|
||||
}
|
||||
|
@ -191,7 +198,8 @@ func TestConfigShouldRejectCustomImageAndMarketPlace(t *testing.T) {
|
|||
|
||||
for _, x := range marketPlace {
|
||||
config[x] = "ignore"
|
||||
_, _, err := newConfig(config, packerConfiguration)
|
||||
var c Config
|
||||
_, err := c.Prepare(config, packerConfiguration)
|
||||
if err == nil {
|
||||
t.Errorf("Expected Config to reject image_url and %s, but it did not", x)
|
||||
}
|
||||
|
@ -212,7 +220,8 @@ func TestConfigVirtualNetworkNameIsOptional(t *testing.T) {
|
|||
"virtual_network_name": "MyVirtualNetwork",
|
||||
}
|
||||
|
||||
c, _, _ := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(config, getPackerConfiguration())
|
||||
if c.VirtualNetworkName != "MyVirtualNetwork" {
|
||||
t.Errorf("Expected Config to set virtual_network_name to MyVirtualNetwork, but got %q", c.VirtualNetworkName)
|
||||
}
|
||||
|
@ -241,7 +250,8 @@ func TestConfigVirtualNetworkResourceGroupNameMustBeSetWithVirtualNetworkName(t
|
|||
"virtual_network_resource_group_name": "MyVirtualNetworkRG",
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Error("Expected Config to reject virtual_network_resource_group_name, if virtual_network_name is not set.")
|
||||
}
|
||||
|
@ -264,7 +274,8 @@ func TestConfigVirtualNetworkSubnetNameMustBeSetWithVirtualNetworkName(t *testin
|
|||
"virtual_network_subnet_name": "MyVirtualNetworkRG",
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Error("Expected Config to reject virtual_network_subnet_name, if virtual_network_name is not set.")
|
||||
}
|
||||
|
@ -284,7 +295,8 @@ func TestConfigAllowedInboundIpAddressesIsOptional(t *testing.T) {
|
|||
"virtual_network_name": "MyVirtualNetwork",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -311,7 +323,8 @@ func TestConfigShouldAcceptCorrectInboundIpAddresses(t *testing.T) {
|
|||
}
|
||||
|
||||
config["allowed_inbound_ip_addresses"] = ipValue0
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -321,7 +334,7 @@ func TestConfigShouldAcceptCorrectInboundIpAddresses(t *testing.T) {
|
|||
}
|
||||
|
||||
config["allowed_inbound_ip_addresses"] = cidrValue2
|
||||
c, _, err = newConfig(config, getPackerConfiguration())
|
||||
_, err = c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -331,7 +344,7 @@ func TestConfigShouldAcceptCorrectInboundIpAddresses(t *testing.T) {
|
|||
}
|
||||
|
||||
config["allowed_inbound_ip_addresses"] = []string{ipValue0, cidrValue2, ipValue1, cidrValue3}
|
||||
c, _, err = newConfig(config, getPackerConfiguration())
|
||||
_, err = c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -357,13 +370,14 @@ func TestConfigShouldRejectIncorrectInboundIpAddresses(t *testing.T) {
|
|||
}
|
||||
|
||||
config["allowed_inbound_ip_addresses"] = []string{"127.0.0.1", "127.0.0.two"}
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Errorf("Expected configuration creation to fail, but it succeeded with the malformed allowed_inbound_ip_addresses set to %v", c.AllowedInboundIpAddresses)
|
||||
}
|
||||
|
||||
config["allowed_inbound_ip_addresses"] = []string{"192.168.100.1000/24", "10.10.1.16/32"}
|
||||
c, _, err = newConfig(config, getPackerConfiguration())
|
||||
_, err = c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
// 192.168.100.1000/24 is invalid
|
||||
t.Errorf("Expected configuration creation to fail, but it succeeded with the malformed allowed_inbound_ip_addresses set to %v", c.AllowedInboundIpAddresses)
|
||||
|
@ -384,20 +398,22 @@ func TestConfigShouldRejectInboundIpAddressesWithVirtualNetwork(t *testing.T) {
|
|||
"allowed_inbound_ip_addresses": "127.0.0.1",
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
config["virtual_network_name"] = "some_vnet_name"
|
||||
_, _, err = newConfig(config, getPackerConfiguration())
|
||||
_, err = c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Errorf("Expected configuration creation to fail, but it succeeded with allowed_inbound_ip_addresses and virtual_network_name both specified")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigShouldDefaultToPublicCloud(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
|
||||
if c.ClientConfig.CloudEnvironmentName != "Public" {
|
||||
t.Errorf("Expected 'CloudEnvironmentName' to default to 'Public', but got '%s'.", c.ClientConfig.CloudEnvironmentName)
|
||||
|
@ -448,7 +464,8 @@ func TestConfigInstantiatesCorrectAzureEnvironment(t *testing.T) {
|
|||
|
||||
for _, x := range table {
|
||||
config["cloud_environment_name"] = x.name
|
||||
c, _, err := newConfig(config, packerConfiguration)
|
||||
var c Config
|
||||
_, err := c.Prepare(config, packerConfiguration)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -463,7 +480,8 @@ func TestUserShouldProvideRequiredValues(t *testing.T) {
|
|||
builderValues := getArmBuilderConfiguration()
|
||||
|
||||
// Ensure we can successfully create a config.
|
||||
_, _, err := newConfig(builderValues, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(builderValues, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Error("Expected configuration creation to succeed, but it failed!\n")
|
||||
t.Fatalf(" -> %+v\n", builderValues)
|
||||
|
@ -474,7 +492,8 @@ func TestUserShouldProvideRequiredValues(t *testing.T) {
|
|||
originalValue := builderValues[v]
|
||||
delete(builderValues, v)
|
||||
|
||||
_, _, err := newConfig(builderValues, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(builderValues, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Error("Expected configuration creation to fail, but it succeeded!\n")
|
||||
t.Fatalf(" -> %+v\n", builderValues)
|
||||
|
@ -485,7 +504,8 @@ func TestUserShouldProvideRequiredValues(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSystemShouldDefineRuntimeValues(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
|
||||
if c.Password == "" {
|
||||
t.Errorf("Expected Password to not be empty, but it was '%s'!", c.Password)
|
||||
|
@ -513,7 +533,8 @@ func TestSystemShouldDefineRuntimeValues(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfigShouldTransformToVirtualMachineCaptureParameters(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
parameters := c.toVirtualMachineCaptureParameters()
|
||||
|
||||
if *parameters.DestinationContainerName != c.CaptureContainerName {
|
||||
|
@ -530,7 +551,8 @@ func TestConfigShouldTransformToVirtualMachineCaptureParameters(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfigShouldSupportPackersConfigElements(t *testing.T) {
|
||||
c, _, err := newConfig(
|
||||
var c Config
|
||||
_, err := c.Prepare(
|
||||
getArmBuilderConfiguration(),
|
||||
getPackerConfiguration(),
|
||||
getPackerCommunicatorConfiguration())
|
||||
|
@ -554,7 +576,8 @@ func TestWinRMConfigShouldSetRoundTripDecorator(t *testing.T) {
|
|||
config["winrm_username"] = "username"
|
||||
config["winrm_password"] = "password"
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -579,7 +602,8 @@ func TestUserDeviceLoginIsEnabledForLinux(t *testing.T) {
|
|||
"communicator": "none",
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatalf("failed to use device login for Linux: %s", err)
|
||||
}
|
||||
|
@ -610,7 +634,8 @@ func TestConfigShouldRejectMalformedCaptureNamePrefix(t *testing.T) {
|
|||
|
||||
for _, x := range wellFormedCaptureNamePrefix {
|
||||
config["capture_name_prefix"] = x
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected test to pass, but it failed with the well-formed capture_name_prefix set to %q.", x)
|
||||
|
@ -628,7 +653,8 @@ func TestConfigShouldRejectMalformedCaptureNamePrefix(t *testing.T) {
|
|||
|
||||
for _, x := range malformedCaptureNamePrefix {
|
||||
config["capture_name_prefix"] = x
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
|
||||
if err == nil {
|
||||
t.Errorf("Expected test to fail, but it succeeded with the malformed capture_name_prefix set to %q.", x)
|
||||
|
@ -660,7 +686,8 @@ func TestConfigShouldRejectMalformedCaptureContainerName(t *testing.T) {
|
|||
|
||||
for _, x := range wellFormedCaptureContainerName {
|
||||
config["capture_container_name"] = x
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected test to pass, but it failed with the well-formed capture_container_name set to %q.", x)
|
||||
|
@ -678,7 +705,8 @@ func TestConfigShouldRejectMalformedCaptureContainerName(t *testing.T) {
|
|||
|
||||
for _, x := range malformedCaptureContainerName {
|
||||
config["capture_container_name"] = x
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
|
||||
if err == nil {
|
||||
t.Errorf("Expected test to fail, but it succeeded with the malformed capture_container_name set to %q.", x)
|
||||
|
@ -710,7 +738,8 @@ func TestConfigShouldRejectMalformedManagedImageOSDiskSnapshotName(t *testing.T)
|
|||
|
||||
for _, x := range wellFormedManagedImageOSDiskSnapshotName {
|
||||
config["managed_image_os_disk_snapshot_name"] = x
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected test to pass, but it failed with the well-formed managed_image_os_disk_snapshot_name set to %q.", x)
|
||||
|
@ -727,7 +756,8 @@ func TestConfigShouldRejectMalformedManagedImageOSDiskSnapshotName(t *testing.T)
|
|||
|
||||
for _, x := range malformedManagedImageOSDiskSnapshotName {
|
||||
config["managed_image_os_disk_snapshot_name"] = x
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
|
||||
if err == nil {
|
||||
t.Errorf("Expected test to fail, but it succeeded with the malformed managed_image_os_disk_snapshot_name set to %q.", x)
|
||||
|
@ -760,7 +790,8 @@ func TestConfigShouldRejectMalformedManagedImageDataDiskSnapshotPrefix(t *testin
|
|||
|
||||
for _, x := range wellFormedManagedImageDataDiskSnapshotPrefix {
|
||||
config["managed_image_data_disk_snapshot_prefix"] = x
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected test to pass, but it failed with the well-formed managed_image_data_disk_snapshot_prefix set to %q.", x)
|
||||
|
@ -777,7 +808,8 @@ func TestConfigShouldRejectMalformedManagedImageDataDiskSnapshotPrefix(t *testin
|
|||
|
||||
for _, x := range malformedManagedImageDataDiskSnapshotPrefix {
|
||||
config["managed_image_data_disk_snapshot_prefix"] = x
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
|
||||
if err == nil {
|
||||
t.Errorf("Expected test to fail, but it succeeded with the malformed managed_image_data_disk_snapshot_prefix set to %q.", x)
|
||||
|
@ -805,7 +837,8 @@ func TestConfigShouldAcceptTags(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -855,7 +888,8 @@ func TestConfigShouldRejectTagsInExcessOf15AcceptTags(t *testing.T) {
|
|||
"azure_tags": tooManyTags,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject based on an excessive amount of tags (> 15)")
|
||||
|
@ -887,7 +921,8 @@ func TestConfigShouldRejectExcessiveTagNameLength(t *testing.T) {
|
|||
"azure_tags": tags,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject tag name based on length (> 512)")
|
||||
}
|
||||
|
@ -918,7 +953,8 @@ func TestConfigShouldRejectExcessiveTagValueLength(t *testing.T) {
|
|||
"azure_tags": tags,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject tag value based on length (> 256)")
|
||||
}
|
||||
|
@ -935,7 +971,8 @@ func TestConfigZoneResilientShouldDefaultToFalse(t *testing.T) {
|
|||
"os_type": "linux",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -958,7 +995,8 @@ func TestConfigZoneResilientSetFromConfig(t *testing.T) {
|
|||
"managed_image_zone_resilient": true,
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -986,7 +1024,8 @@ func TestConfigShouldRejectMissingCustomDataFile(t *testing.T) {
|
|||
"custom_data_file": "/this/file/does/not/exist",
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject missing custom data file")
|
||||
}
|
||||
|
@ -1006,7 +1045,8 @@ func TestConfigShouldRejectManagedImageOSDiskSnapshotNameWithoutManagedImageName
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject Managed Image build with OS disk snapshot name but without managed image name")
|
||||
}
|
||||
|
@ -1026,7 +1066,8 @@ func TestConfigShouldRejectManagedImageOSDiskSnapshotNameWithoutManagedImageReso
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject Managed Image build with OS disk snapshot name but without managed image resource group name")
|
||||
}
|
||||
|
@ -1046,7 +1087,8 @@ func TestConfigShouldRejectImageDataDiskSnapshotPrefixWithoutManagedImageName(t
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject Managed Image build with data disk snapshot prefix but without managed image name")
|
||||
}
|
||||
|
@ -1066,7 +1108,8 @@ func TestConfigShouldRejectImageDataDiskSnapshotPrefixWithoutManagedImageResourc
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject Managed Image build with data disk snapshot prefix but without managed image resource group name")
|
||||
}
|
||||
|
@ -1088,7 +1131,8 @@ func TestConfigShouldAcceptManagedImageOSDiskSnapshotNameAndManagedImageDataDisk
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal("expected config to accept platform managed image build")
|
||||
}
|
||||
|
@ -1109,7 +1153,8 @@ func TestConfigShouldRejectManagedImageOSDiskSnapshotNameAndManagedImageDataDisk
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject Managed Image build with data disk snapshot prefix and OS disk snapshot name with capture container name")
|
||||
}
|
||||
|
@ -1130,7 +1175,8 @@ func TestConfigShouldRejectManagedImageOSDiskSnapshotNameAndManagedImageDataDisk
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject Managed Image build with data disk snapshot prefix and OS disk snapshot name with capture name prefix")
|
||||
}
|
||||
|
@ -1151,7 +1197,8 @@ func TestConfigShouldAcceptPlatformManagedImageBuild(t *testing.T) {
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal("expected config to accept platform managed image build")
|
||||
}
|
||||
|
@ -1175,7 +1222,8 @@ func TestConfigShouldRejectVhdAndManagedImageOutput(t *testing.T) {
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject VHD and Managed Image build")
|
||||
}
|
||||
|
@ -1195,7 +1243,8 @@ func TestConfigShouldRejectManagedImageSourceAndVhdOutput(t *testing.T) {
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject VHD and Managed Image build")
|
||||
}
|
||||
|
@ -1218,7 +1267,8 @@ func TestConfigShouldRejectCustomAndPlatformManagedImageBuild(t *testing.T) {
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject custom and platform input for a managed image build")
|
||||
}
|
||||
|
@ -1239,7 +1289,8 @@ func TestConfigShouldRejectCustomAndImageUrlForManagedImageBuild(t *testing.T) {
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject custom and platform input for a managed image build")
|
||||
}
|
||||
|
@ -1260,7 +1311,8 @@ func TestConfigShouldRejectMalformedManageImageStorageAccountTypes(t *testing.T)
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject custom and platform input for a managed image build")
|
||||
}
|
||||
|
@ -1281,7 +1333,8 @@ func TestConfigShouldRejectMalformedDiskCachingType(t *testing.T) {
|
|||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject custom and platform input for a managed image build")
|
||||
}
|
||||
|
@ -1305,7 +1358,8 @@ func TestConfigShouldAcceptManagedImageStorageAccountTypes(t *testing.T) {
|
|||
|
||||
for _, x := range storage_account_types {
|
||||
config["managed_image_storage_account_type"] = x
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatalf("expected config to accept a managed_image_storage_account_type of %q", x)
|
||||
}
|
||||
|
@ -1330,7 +1384,8 @@ func TestConfigShouldAcceptDiskCachingTypes(t *testing.T) {
|
|||
|
||||
for _, x := range storage_account_types {
|
||||
config["disk_caching_type"] = x
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatalf("expected config to accept a disk_caching_type of %q", x)
|
||||
}
|
||||
|
@ -1355,7 +1410,8 @@ func TestConfigShouldRejectTempAndBuildResourceGroupName(t *testing.T) {
|
|||
"build_resource_group_name": "rgn00",
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject the use of both temp_resource_group_name and build_resource_group_name")
|
||||
}
|
||||
|
@ -1402,7 +1458,8 @@ func TestConfigShouldRejectInvalidResourceGroupNames(t *testing.T) {
|
|||
for _, y := range tests {
|
||||
config[x] = y.name
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if !y.ok && err == nil {
|
||||
t.Errorf("expected config to reject %q for setting %q", y.name, x)
|
||||
} else if y.ok && err != nil {
|
||||
|
@ -1452,7 +1509,8 @@ func TestConfigShouldRejectManagedDiskNames(t *testing.T) {
|
|||
for _, y := range testsResourceGroupNames {
|
||||
config[settingUnderTest] = y.name
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if !y.ok && err == nil {
|
||||
t.Errorf("expected config to reject %q for setting %q", y.name, settingUnderTest)
|
||||
} else if y.ok && err != nil {
|
||||
|
@ -1486,7 +1544,8 @@ func TestConfigShouldRejectManagedDiskNames(t *testing.T) {
|
|||
for _, y := range testNames {
|
||||
config[settingUnderTest] = y.name
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if !y.ok && err == nil {
|
||||
t.Logf("expected config to reject %q for setting %q", y.name, settingUnderTest)
|
||||
} else if y.ok && err != nil {
|
||||
|
@ -1496,7 +1555,8 @@ func TestConfigShouldRejectManagedDiskNames(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfigAdditionalDiskDefaultIsNil(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
if c.AdditionalDiskSize != nil {
|
||||
t.Errorf("Expected Config to not have a set of additional disks, but got a non nil value")
|
||||
}
|
||||
|
@ -1519,7 +1579,8 @@ func TestConfigAdditionalDiskOverrideDefault(t *testing.T) {
|
|||
"disk_additional_size": {32, 64},
|
||||
}
|
||||
|
||||
c, _, _ := newConfig(config, diskconfig, getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(config, diskconfig, getPackerConfiguration())
|
||||
if c.AdditionalDiskSize == nil {
|
||||
t.Errorf("Expected Config to have a set of additional disks, but got nil")
|
||||
}
|
||||
|
@ -1561,19 +1622,20 @@ func TestPlanInfoConfiguration(t *testing.T) {
|
|||
}
|
||||
config["plan_info"] = planInfo
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject the use of plan_name without plan_product and plan_publisher")
|
||||
}
|
||||
|
||||
planInfo["plan_product"] = "--plan-product--"
|
||||
_, _, err = newConfig(config, getPackerConfiguration())
|
||||
_, err = c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject the use of plan_name and plan_product without plan_publisher")
|
||||
}
|
||||
|
||||
planInfo["plan_publisher"] = "--plan-publisher--"
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
_, err = c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatalf("expected config to accept a complete plan configuration: %s", err)
|
||||
}
|
||||
|
@ -1610,7 +1672,8 @@ func TestPlanInfoPromotionCode(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatalf("expected config to accept plan_info configuration, but got %s", err)
|
||||
}
|
||||
|
@ -1659,7 +1722,8 @@ func TestPlanInfoTooManyTagsErrors(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Fatal("expected config to reject configuration due to excess tags")
|
||||
}
|
||||
|
@ -1682,7 +1746,8 @@ func TestConfigShouldAllowTempNameOverrides(t *testing.T) {
|
|||
"temp_compute_name": "myTempComputeName",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Errorf("newConfig failed with %q", err)
|
||||
}
|
||||
|
@ -1716,7 +1781,8 @@ func TestConfigShouldAllowAsyncResourceGroupOverride(t *testing.T) {
|
|||
"async_resourcegroup_delete": "true",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Errorf("newConfig failed with %q", err)
|
||||
}
|
||||
|
@ -1738,7 +1804,8 @@ func TestConfigShouldAllowAsyncResourceGroupOverrideNoValue(t *testing.T) {
|
|||
"managed_image_resource_group_name": "ignore",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Errorf("newConfig failed with %q", err)
|
||||
}
|
||||
|
@ -1761,10 +1828,10 @@ func TestConfigShouldAllowAsyncResourceGroupOverrideBadValue(t *testing.T) {
|
|||
"async_resourcegroup_delete": "asdasda",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
if err != nil && c == nil {
|
||||
t.Log("newConfig failed which is expected ", err)
|
||||
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Log("newConfig failed which is expected ", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1782,7 +1849,8 @@ func TestConfigShouldAllowSharedImageGalleryOptions(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err == nil {
|
||||
t.Log("expected config to accept Shared Image Gallery options", err)
|
||||
}
|
||||
|
@ -1807,7 +1875,8 @@ func TestConfigShouldRejectSharedImageGalleryWithVhdTarget(t *testing.T) {
|
|||
"capture_name_prefix": "ignore",
|
||||
}
|
||||
|
||||
_, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Log("expected an error if Shared Image Gallery source is used with VHD target", err)
|
||||
}
|
||||
|
@ -1818,7 +1887,8 @@ func Test_GivenZoneNotSupportingResiliency_ConfigValidate_ShouldWarn(t *testing.
|
|||
builderValues["managed_image_zone_resilient"] = "true"
|
||||
builderValues["location"] = "ukwest"
|
||||
|
||||
c, _, err := newConfig(builderValues, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(builderValues, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Errorf("newConfig failed with %q", err)
|
||||
}
|
||||
|
@ -1836,7 +1906,8 @@ func Test_GivenZoneSupportingResiliency_ConfigValidate_ShouldNotWarn(t *testing.
|
|||
builderValues["managed_image_zone_resilient"] = "true"
|
||||
builderValues["location"] = "westeurope"
|
||||
|
||||
c, _, err := newConfig(builderValues, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(builderValues, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Errorf("newConfig failed with %q", err)
|
||||
}
|
||||
|
|
|
@ -5,14 +5,15 @@ import (
|
|||
)
|
||||
|
||||
func TestResourceResolverIgnoresEmptyVirtualNetworkName(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
if c.VirtualNetworkName != "" {
|
||||
t.Fatalf("Expected VirtualNetworkName to be empty by default")
|
||||
}
|
||||
|
||||
sut := newTestResourceResolver()
|
||||
sut.findVirtualNetworkResourceGroup = nil // assert that this is not even called
|
||||
sut.Resolve(c)
|
||||
sut.Resolve(&c)
|
||||
|
||||
if c.VirtualNetworkName != "" {
|
||||
t.Fatalf("Expected VirtualNetworkName to be empty")
|
||||
|
@ -25,7 +26,8 @@ func TestResourceResolverIgnoresEmptyVirtualNetworkName(t *testing.T) {
|
|||
// If the user fully specified the virtual network name and resource group then
|
||||
// there is no need to do a lookup.
|
||||
func TestResourceResolverIgnoresSetVirtualNetwork(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
c.VirtualNetworkName = "--virtual-network-name--"
|
||||
c.VirtualNetworkResourceGroupName = "--virtual-network-resource-group-name--"
|
||||
c.VirtualNetworkSubnetName = "--virtual-network-subnet-name--"
|
||||
|
@ -33,7 +35,7 @@ func TestResourceResolverIgnoresSetVirtualNetwork(t *testing.T) {
|
|||
sut := newTestResourceResolver()
|
||||
sut.findVirtualNetworkResourceGroup = nil // assert that this is not even called
|
||||
sut.findVirtualNetworkSubnet = nil // assert that this is not even called
|
||||
sut.Resolve(c)
|
||||
sut.Resolve(&c)
|
||||
|
||||
if c.VirtualNetworkName != "--virtual-network-name--" {
|
||||
t.Fatalf("Expected VirtualNetworkName to be --virtual-network-name--")
|
||||
|
@ -49,11 +51,12 @@ func TestResourceResolverIgnoresSetVirtualNetwork(t *testing.T) {
|
|||
// If the user set virtual network name then the code should resolve virtual network
|
||||
// resource group name.
|
||||
func TestResourceResolverSetVirtualNetworkResourceGroupName(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
c.VirtualNetworkName = "--virtual-network-name--"
|
||||
|
||||
sut := newTestResourceResolver()
|
||||
sut.Resolve(c)
|
||||
sut.Resolve(&c)
|
||||
|
||||
if c.VirtualNetworkResourceGroupName != "findVirtualNetworkResourceGroup is mocked" {
|
||||
t.Fatalf("Expected VirtualNetworkResourceGroupName to be 'findVirtualNetworkResourceGroup is mocked'")
|
||||
|
|
|
@ -3,7 +3,9 @@ package arm
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-03-01/compute"
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
"github.com/hashicorp/packer/builder/azure/common/constants"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
@ -11,7 +13,7 @@ import (
|
|||
|
||||
type StepPublishToSharedImageGallery struct {
|
||||
client *AzureClient
|
||||
publish func(ctx context.Context, mdiID, miSigPubRg, miSIGalleryName, miSGImageName, miSGImageVersion string, miSigReplicationRegions []string, location string, tags map[string]*string) (string, error)
|
||||
publish func(ctx context.Context, mdiID, miSigPubRg, miSIGalleryName, miSGImageName, miSGImageVersion string, miSigReplicationRegions []string, miSGImageVersionEndOfLifeDate string, miSGImageVersionExcludeFromLatest bool, miSigReplicaCount int32, location string, tags map[string]*string) (string, error)
|
||||
say func(message string)
|
||||
error func(e error)
|
||||
toSIG func() bool
|
||||
|
@ -35,7 +37,7 @@ func NewStepPublishToSharedImageGallery(client *AzureClient, ui packer.Ui, confi
|
|||
return step
|
||||
}
|
||||
|
||||
func (s *StepPublishToSharedImageGallery) publishToSig(ctx context.Context, mdiID string, miSigPubRg string, miSIGalleryName string, miSGImageName string, miSGImageVersion string, miSigReplicationRegions []string, location string, tags map[string]*string) (string, error) {
|
||||
func (s *StepPublishToSharedImageGallery) publishToSig(ctx context.Context, mdiID string, miSigPubRg string, miSIGalleryName string, miSGImageName string, miSGImageVersion string, miSigReplicationRegions []string, miSGImageVersionEndOfLifeDate string, miSGImageVersionExcludeFromLatest bool, miSigReplicaCount int32, location string, tags map[string]*string) (string, error) {
|
||||
|
||||
replicationRegions := make([]compute.TargetRegion, len(miSigReplicationRegions))
|
||||
for i, v := range miSigReplicationRegions {
|
||||
|
@ -43,6 +45,17 @@ func (s *StepPublishToSharedImageGallery) publishToSig(ctx context.Context, mdiI
|
|||
replicationRegions[i] = compute.TargetRegion{Name: ®ionName}
|
||||
}
|
||||
|
||||
var endOfLifeDate *date.Time
|
||||
if miSGImageVersionEndOfLifeDate != "" {
|
||||
parseDate, err := date.ParseTime("2006-01-02T15:04:05.99Z", miSGImageVersionEndOfLifeDate)
|
||||
if err != nil {
|
||||
s.say(fmt.Sprintf("Error parsing date from shared_gallery_image_version_end_of_life_date: %s", err))
|
||||
return "", err
|
||||
}
|
||||
endOfLifeDate = &date.Time{Time: parseDate}
|
||||
} else {
|
||||
endOfLifeDate = (*date.Time)(nil)
|
||||
}
|
||||
galleryImageVersion := compute.GalleryImageVersion{
|
||||
Location: &location,
|
||||
Tags: tags,
|
||||
|
@ -53,7 +66,10 @@ func (s *StepPublishToSharedImageGallery) publishToSig(ctx context.Context, mdiI
|
|||
ID: &mdiID,
|
||||
},
|
||||
},
|
||||
TargetRegions: &replicationRegions,
|
||||
TargetRegions: &replicationRegions,
|
||||
EndOfLifeDate: endOfLifeDate,
|
||||
ExcludeFromLatest: &miSGImageVersionExcludeFromLatest,
|
||||
ReplicaCount: &miSigReplicaCount,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -101,14 +117,27 @@ func (s *StepPublishToSharedImageGallery) Run(ctx context.Context, stateBag mult
|
|||
var targetManagedImageName = stateBag.Get(constants.ArmManagedImageName).(string)
|
||||
var managedImageSubscription = stateBag.Get(constants.ArmManagedImageSubscription).(string)
|
||||
var mdiID = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/images/%s", managedImageSubscription, targetManagedImageResourceGroupName, targetManagedImageName)
|
||||
miSGImageVersionEndOfLifeDate, _ := stateBag.Get(constants.ArmManagedImageSharedGalleryImageVersionEndOfLifeDate).(string)
|
||||
miSGImageVersionExcludeFromLatest, _ := stateBag.Get(constants.ArmManagedImageSharedGalleryImageVersionExcludeFromLatest).(bool)
|
||||
miSigReplicaCount, _ := stateBag.Get(constants.ArmManagedImageSharedGalleryImageVersionReplicaCount).(int32)
|
||||
// Replica count must be between 1 and 10 inclusive.
|
||||
if miSigReplicaCount <= 0 {
|
||||
miSigReplicaCount = constants.SharedImageGalleryImageVersionDefaultMinReplicaCount
|
||||
} else if miSigReplicaCount > 10 {
|
||||
miSigReplicaCount = constants.SharedImageGalleryImageVersionDefaultMaxReplicaCount
|
||||
}
|
||||
|
||||
s.say(fmt.Sprintf(" -> MDI ID used for SIG publish : '%s'", mdiID))
|
||||
s.say(fmt.Sprintf(" -> SIG publish resource group : '%s'", miSigPubRg))
|
||||
s.say(fmt.Sprintf(" -> SIG gallery name : '%s'", miSIGalleryName))
|
||||
s.say(fmt.Sprintf(" -> SIG image name : '%s'", miSGImageName))
|
||||
s.say(fmt.Sprintf(" -> SIG image version : '%s'", miSGImageVersion))
|
||||
s.say(fmt.Sprintf(" -> SIG replication regions : '%v'", miSigReplicationRegions))
|
||||
createdGalleryImageVersionID, err := s.publish(ctx, mdiID, miSigPubRg, miSIGalleryName, miSGImageName, miSGImageVersion, miSigReplicationRegions, location, tags)
|
||||
s.say(fmt.Sprintf(" -> MDI ID used for SIG publish : '%s'", mdiID))
|
||||
s.say(fmt.Sprintf(" -> SIG publish resource group : '%s'", miSigPubRg))
|
||||
s.say(fmt.Sprintf(" -> SIG gallery name : '%s'", miSIGalleryName))
|
||||
s.say(fmt.Sprintf(" -> SIG image name : '%s'", miSGImageName))
|
||||
s.say(fmt.Sprintf(" -> SIG image version : '%s'", miSGImageVersion))
|
||||
s.say(fmt.Sprintf(" -> SIG replication regions : '%v'", miSigReplicationRegions))
|
||||
s.say(fmt.Sprintf(" -> SIG image version endoflife date : '%s'", miSGImageVersionEndOfLifeDate))
|
||||
s.say(fmt.Sprintf(" -> SIG image version exclude from latest : '%t'", miSGImageVersionExcludeFromLatest))
|
||||
s.say(fmt.Sprintf(" -> SIG replica count [1, 10] : '%d'", miSigReplicaCount))
|
||||
|
||||
createdGalleryImageVersionID, err := s.publish(ctx, mdiID, miSigPubRg, miSIGalleryName, miSGImageName, miSGImageVersion, miSigReplicationRegions, miSGImageVersionEndOfLifeDate, miSGImageVersionExcludeFromLatest, miSigReplicaCount, location, tags)
|
||||
|
||||
if err != nil {
|
||||
stateBag.Put(constants.Error, err)
|
||||
|
|
|
@ -2,14 +2,15 @@ package arm
|
|||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer/builder/azure/common/constants"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStepPublishToSharedImageGalleryShouldNotPublishForVhd(t *testing.T) {
|
||||
var testSubject = &StepPublishToSharedImageGallery{
|
||||
publish: func(context.Context, string, string, string, string, string, []string, string, map[string]*string) (string, error) {
|
||||
publish: func(context.Context, string, string, string, string, string, []string, string, bool, int32, string, map[string]*string) (string, error) {
|
||||
return "test", nil
|
||||
},
|
||||
say: func(message string) {},
|
||||
|
@ -30,7 +31,7 @@ func TestStepPublishToSharedImageGalleryShouldNotPublishForVhd(t *testing.T) {
|
|||
|
||||
func TestStepPublishToSharedImageGalleryShouldPublishForManagedImageWithSig(t *testing.T) {
|
||||
var testSubject = &StepPublishToSharedImageGallery{
|
||||
publish: func(context.Context, string, string, string, string, string, []string, string, map[string]*string) (string, error) {
|
||||
publish: func(context.Context, string, string, string, string, string, []string, string, bool, int32, string, map[string]*string) (string, error) {
|
||||
return "", nil
|
||||
},
|
||||
say: func(message string) {},
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package arm
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
commonhelper "github.com/hashicorp/packer/helper/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type StepSaveWinRMPassword struct {
|
||||
Password string
|
||||
BuildName string
|
||||
}
|
||||
|
||||
func (s *StepSaveWinRMPassword) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
// store so that we can access this later during provisioning
|
||||
commonhelper.SetSharedState("winrm_password", s.Password, s.BuildName)
|
||||
packer.LogSecretFilter.Set(s.Password)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *StepSaveWinRMPassword) Cleanup(multistep.StateBag) {
|
||||
commonhelper.RemoveSharedStateFile("winrm_password", s.BuildName)
|
||||
}
|
|
@ -13,8 +13,9 @@ import (
|
|||
|
||||
// Ensure the link values are not set, and the concrete values are set.
|
||||
func TestVirtualMachineDeployment00(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -42,8 +43,9 @@ func TestVirtualMachineDeployment00(t *testing.T) {
|
|||
|
||||
// Ensure the Virtual Machine template is a valid JSON document.
|
||||
func TestVirtualMachineDeployment01(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -56,8 +58,9 @@ func TestVirtualMachineDeployment01(t *testing.T) {
|
|||
|
||||
// Ensure the Virtual Machine template parameters are correct.
|
||||
func TestVirtualMachineDeployment02(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -104,8 +107,9 @@ func TestVirtualMachineDeployment03(t *testing.T) {
|
|||
m["image_sku"] = "ImageSku"
|
||||
m["image_version"] = "ImageVersion"
|
||||
|
||||
c, _, _ := newConfig(m, getPackerConfiguration())
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
var c Config
|
||||
c.Prepare(m, getPackerConfiguration())
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -130,12 +134,13 @@ func TestVirtualMachineDeployment04(t *testing.T) {
|
|||
"communicator": "none",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -162,12 +167,13 @@ func TestVirtualMachineDeployment05(t *testing.T) {
|
|||
"virtual_network_subnet_name": "virtualNetworkSubnetName",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -197,12 +203,13 @@ func TestVirtualMachineDeployment06(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -227,7 +234,8 @@ func TestVirtualMachineDeployment07(t *testing.T) {
|
|||
"communicator": "none",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -247,7 +255,7 @@ growpart:
|
|||
base64CustomData := base64.StdEncoding.EncodeToString([]byte(customData))
|
||||
c.customData = base64CustomData
|
||||
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -271,12 +279,13 @@ func TestVirtualMachineDeployment08(t *testing.T) {
|
|||
"managed_image_resource_group_name": "ManagedImageResourceGroupName",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -302,12 +311,13 @@ func TestVirtualMachineDeployment09(t *testing.T) {
|
|||
"managed_image_resource_group_name": "ManagedImageResourceGroupName",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -339,12 +349,13 @@ func TestVirtualMachineDeployment10(t *testing.T) {
|
|||
"managed_image_resource_group_name": "ManagedImageResourceGroupName",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -375,12 +386,13 @@ func TestVirtualMachineDeployment11(t *testing.T) {
|
|||
"capture_container_name": "packerimages",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -409,12 +421,13 @@ func TestVirtualMachineDeployment12(t *testing.T) {
|
|||
"managed_image_resource_group_name": "ManagedImageResourceGroupName",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -442,13 +455,14 @@ func TestVirtualMachineDeployment13(t *testing.T) {
|
|||
"allowed_inbound_ip_addresses": []string{"127.0.0.1", "192.168.100.0/24"},
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
var c Config
|
||||
_, err := c.Prepare(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
c.tmpKeyVaultName = "--keyvault-name--"
|
||||
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -461,8 +475,9 @@ func TestVirtualMachineDeployment13(t *testing.T) {
|
|||
|
||||
// Ensure the link values are not set, and the concrete values are set.
|
||||
func TestKeyVaultDeployment00(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetKeyVaultDeployment(c)
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetKeyVaultDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -490,8 +505,9 @@ func TestKeyVaultDeployment00(t *testing.T) {
|
|||
|
||||
// Ensure the KeyVault template is a valid JSON document.
|
||||
func TestKeyVaultDeployment01(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetKeyVaultDeployment(c)
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetKeyVaultDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -504,9 +520,10 @@ func TestKeyVaultDeployment01(t *testing.T) {
|
|||
|
||||
// Ensure the KeyVault template parameters are correct.
|
||||
func TestKeyVaultDeployment02(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfigurationWithWindows(), getPackerConfiguration())
|
||||
var c Config
|
||||
c.Prepare(getArmBuilderConfigurationWithWindows(), getPackerConfiguration())
|
||||
|
||||
deployment, err := GetKeyVaultDeployment(c)
|
||||
deployment, err := GetKeyVaultDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -546,8 +563,9 @@ func TestKeyVaultDeployment03(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
c, _, _ := newConfig(tags, getArmBuilderConfigurationWithWindows(), getPackerConfiguration())
|
||||
deployment, err := GetKeyVaultDeployment(c)
|
||||
var c Config
|
||||
c.Prepare(tags, getArmBuilderConfigurationWithWindows(), getPackerConfiguration())
|
||||
deployment, err := GetKeyVaultDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -567,8 +585,9 @@ func TestPlanInfo01(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
c, _, _ := newConfig(planInfo, getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
var c Config
|
||||
c.Prepare(planInfo, getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -592,8 +611,9 @@ func TestPlanInfo02(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
c, _, _ := newConfig(planInfo, getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
var c Config
|
||||
c.Prepare(planInfo, getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
deployment, err := GetVirtualMachineDeployment(&c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//go:generate struct-markdown
|
||||
//go:generate mapstructure-to-hcl2 -type Config
|
||||
|
||||
// Package chroot is able to create an Azure managed image without requiring the
|
||||
// launch of a new virtual machine for every build. It does this by attaching and
|
||||
|
@ -14,6 +15,7 @@ import (
|
|||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
azcommon "github.com/hashicorp/packer/builder/azure/common"
|
||||
"github.com/hashicorp/packer/builder/azure/common/client"
|
||||
"github.com/hashicorp/packer/common"
|
||||
|
@ -116,7 +118,9 @@ type Builder struct {
|
|||
runner multistep.Runner
|
||||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
b.config.ctx.Funcs = azcommon.TemplateFuncs
|
||||
b.config.ctx.Funcs["vm"] = CreateVMMetadataTemplateFunc()
|
||||
err := config.Decode(&b.config, &config.DecodeOpts{
|
||||
|
@ -134,7 +138,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var errs *packer.MultiError
|
||||
|
@ -143,7 +147,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
// Defaults
|
||||
err = b.config.ClientConfig.SetDefaultValues()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if b.config.ChrootMounts == nil {
|
||||
|
@ -254,11 +258,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
}
|
||||
|
||||
if errs != nil {
|
||||
return warns, errs
|
||||
return nil, warns, errs
|
||||
}
|
||||
|
||||
packer.LogSecretFilter.Set(b.config.ClientConfig.ClientSecret, b.config.ClientConfig.ClientJWT)
|
||||
return warns, nil
|
||||
return nil, warns, nil
|
||||
}
|
||||
|
||||
func checkDiskCacheType(s string) interface{} {
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
// Code generated by "mapstructure-to-hcl2 -type Config"; DO NOT EDIT.
|
||||
package chroot
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatConfig struct {
|
||||
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
|
||||
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
|
||||
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
|
||||
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
|
||||
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
|
||||
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
|
||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
|
||||
CloudEnvironmentName *string `mapstructure:"cloud_environment_name" required:"false" cty:"cloud_environment_name"`
|
||||
ClientID *string `mapstructure:"client_id" cty:"client_id"`
|
||||
ClientSecret *string `mapstructure:"client_secret" cty:"client_secret"`
|
||||
ClientCertPath *string `mapstructure:"client_cert_path" cty:"client_cert_path"`
|
||||
ClientJWT *string `mapstructure:"client_jwt" cty:"client_jwt"`
|
||||
ObjectID *string `mapstructure:"object_id" cty:"object_id"`
|
||||
TenantID *string `mapstructure:"tenant_id" required:"false" cty:"tenant_id"`
|
||||
SubscriptionID *string `mapstructure:"subscription_id" cty:"subscription_id"`
|
||||
FromScratch *bool `mapstructure:"from_scratch" cty:"from_scratch"`
|
||||
Source *string `mapstructure:"source" required:"true" cty:"source"`
|
||||
CommandWrapper *string `mapstructure:"command_wrapper" cty:"command_wrapper"`
|
||||
PreMountCommands []string `mapstructure:"pre_mount_commands" cty:"pre_mount_commands"`
|
||||
MountOptions []string `mapstructure:"mount_options" cty:"mount_options"`
|
||||
MountPartition *string `mapstructure:"mount_partition" cty:"mount_partition"`
|
||||
MountPath *string `mapstructure:"mount_path" cty:"mount_path"`
|
||||
PostMountCommands []string `mapstructure:"post_mount_commands" cty:"post_mount_commands"`
|
||||
ChrootMounts [][]string `mapstructure:"chroot_mounts" cty:"chroot_mounts"`
|
||||
CopyFiles []string `mapstructure:"copy_files" cty:"copy_files"`
|
||||
TemporaryOSDiskName *string `mapstructure:"temporary_os_disk_name" cty:"temporary_os_disk_name"`
|
||||
OSDiskSizeGB *int32 `mapstructure:"os_disk_size_gb" cty:"os_disk_size_gb"`
|
||||
OSDiskStorageAccountType *string `mapstructure:"os_disk_storage_account_type" cty:"os_disk_storage_account_type"`
|
||||
OSDiskCacheType *string `mapstructure:"os_disk_cache_type" cty:"os_disk_cache_type"`
|
||||
OSDiskSkipCleanup *bool `mapstructure:"os_disk_skip_cleanup" cty:"os_disk_skip_cleanup"`
|
||||
ImageResourceID *string `mapstructure:"image_resource_id" required:"true" cty:"image_resource_id"`
|
||||
ImageHyperVGeneration *string `mapstructure:"image_hyperv_generation" cty:"image_hyperv_generation"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
|
||||
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
|
||||
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
|
||||
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
|
||||
"packer_user_variables": &hcldec.BlockAttrsSpec{TypeName: "packer_user_variables", ElementType: cty.String, Required: false},
|
||||
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
|
||||
"cloud_environment_name": &hcldec.AttrSpec{Name: "cloud_environment_name", Type: cty.String, Required: false},
|
||||
"client_id": &hcldec.AttrSpec{Name: "client_id", Type: cty.String, Required: false},
|
||||
"client_secret": &hcldec.AttrSpec{Name: "client_secret", Type: cty.String, Required: false},
|
||||
"client_cert_path": &hcldec.AttrSpec{Name: "client_cert_path", Type: cty.String, Required: false},
|
||||
"client_jwt": &hcldec.AttrSpec{Name: "client_jwt", Type: cty.String, Required: false},
|
||||
"object_id": &hcldec.AttrSpec{Name: "object_id", Type: cty.String, Required: false},
|
||||
"tenant_id": &hcldec.AttrSpec{Name: "tenant_id", Type: cty.String, Required: false},
|
||||
"subscription_id": &hcldec.AttrSpec{Name: "subscription_id", Type: cty.String, Required: false},
|
||||
"from_scratch": &hcldec.AttrSpec{Name: "from_scratch", Type: cty.Bool, Required: false},
|
||||
"source": &hcldec.AttrSpec{Name: "source", Type: cty.String, Required: false},
|
||||
"command_wrapper": &hcldec.AttrSpec{Name: "command_wrapper", Type: cty.String, Required: false},
|
||||
"pre_mount_commands": &hcldec.AttrSpec{Name: "pre_mount_commands", Type: cty.List(cty.String), Required: false},
|
||||
"mount_options": &hcldec.AttrSpec{Name: "mount_options", Type: cty.List(cty.String), Required: false},
|
||||
"mount_partition": &hcldec.AttrSpec{Name: "mount_partition", Type: cty.String, Required: false},
|
||||
"mount_path": &hcldec.AttrSpec{Name: "mount_path", Type: cty.String, Required: false},
|
||||
"post_mount_commands": &hcldec.AttrSpec{Name: "post_mount_commands", Type: cty.List(cty.String), Required: false},
|
||||
"chroot_mounts": &hcldec.BlockListSpec{TypeName: "chroot_mounts", Nested: &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.String), Required: false}},
|
||||
"copy_files": &hcldec.AttrSpec{Name: "copy_files", Type: cty.List(cty.String), Required: false},
|
||||
"temporary_os_disk_name": &hcldec.AttrSpec{Name: "temporary_os_disk_name", Type: cty.String, Required: false},
|
||||
"os_disk_size_gb": &hcldec.AttrSpec{Name: "os_disk_size_gb", Type: cty.Number, Required: false},
|
||||
"os_disk_storage_account_type": &hcldec.AttrSpec{Name: "os_disk_storage_account_type", Type: cty.String, Required: false},
|
||||
"os_disk_cache_type": &hcldec.AttrSpec{Name: "os_disk_cache_type", Type: cty.String, Required: false},
|
||||
"os_disk_skip_cleanup": &hcldec.AttrSpec{Name: "os_disk_skip_cleanup", Type: cty.Bool, Required: false},
|
||||
"image_resource_id": &hcldec.AttrSpec{Name: "image_resource_id", Type: cty.String, Required: false},
|
||||
"image_hyperv_generation": &hcldec.AttrSpec{Name: "image_hyperv_generation", Type: cty.String, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
|
@ -55,7 +55,7 @@ func TestBuilder_Prepare(t *testing.T) {
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
b := &Builder{}
|
||||
|
||||
_, err := b.Prepare(tt.config)
|
||||
_, _, err := b.Prepare(tt.config)
|
||||
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("Builder.Prepare() error = %v, wantErr %v", err, tt.wantErr)
|
||||
|
|
|
@ -2,9 +2,10 @@ package chroot
|
|||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-03-01/compute"
|
||||
"github.com/hashicorp/packer/builder/azure/common/client"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
|
@ -3,13 +3,14 @@ package chroot
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-03-01/compute"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
"github.com/hashicorp/packer/builder/azure/common/client"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"log"
|
||||
)
|
||||
|
||||
var _ multistep.Step = &StepCreateImage{}
|
||||
|
|
|
@ -3,11 +3,12 @@ package client
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/profiles/latest/compute/mgmt/compute"
|
||||
"github.com/Azure/azure-sdk-for-go/profiles/latest/compute/mgmt/compute/computeapi"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var platformImageRegex = regexp.MustCompile(`^[-_.a-zA-Z0-9]+:[-_.a-zA-Z0-9]+:[-_.a-zA-Z0-9]+:[-_.a-zA-Z0-9]+$`)
|
||||
|
|
|
@ -9,6 +9,13 @@ const (
|
|||
Thumbprint string = "thumbprint"
|
||||
Ui string = "ui"
|
||||
)
|
||||
|
||||
// Default replica count for image versions in shared image gallery
|
||||
const (
|
||||
SharedImageGalleryImageVersionDefaultMinReplicaCount int32 = 1
|
||||
SharedImageGalleryImageVersionDefaultMaxReplicaCount int32 = 10
|
||||
)
|
||||
|
||||
const (
|
||||
ArmCaptureTemplate string = "arm.CaptureTemplate"
|
||||
ArmComputeName string = "arm.ComputeName"
|
||||
|
@ -30,18 +37,21 @@ const (
|
|||
ArmVirtualMachineCaptureParameters string = "arm.VirtualMachineCaptureParameters"
|
||||
ArmIsExistingResourceGroup string = "arm.IsExistingResourceGroup"
|
||||
|
||||
ArmIsManagedImage string = "arm.IsManagedImage"
|
||||
ArmManagedImageResourceGroupName string = "arm.ManagedImageResourceGroupName"
|
||||
ArmManagedImageLocation string = "arm.ManagedImageLocation"
|
||||
ArmManagedImageName string = "arm.ManagedImageName"
|
||||
ArmManagedImageSigPublishResourceGroup string = "arm.ManagedImageSigPublishResourceGroup"
|
||||
ArmManagedImageSharedGalleryName string = "arm.ManagedImageSharedGalleryName"
|
||||
ArmManagedImageSharedGalleryImageName string = "arm.ManagedImageSharedGalleryImageName"
|
||||
ArmManagedImageSharedGalleryImageVersion string = "arm.ManagedImageSharedGalleryImageVersion"
|
||||
ArmManagedImageSharedGalleryReplicationRegions string = "arm.ManagedImageSharedGalleryReplicationRegions"
|
||||
ArmManagedImageSharedGalleryId string = "arm.ArmManagedImageSharedGalleryId"
|
||||
ArmManagedImageSubscription string = "arm.ArmManagedImageSubscription"
|
||||
ArmAsyncResourceGroupDelete string = "arm.AsyncResourceGroupDelete"
|
||||
ArmManagedImageOSDiskSnapshotName string = "arm.ManagedImageOSDiskSnapshotName"
|
||||
ArmManagedImageDataDiskSnapshotPrefix string = "arm.ManagedImageDataDiskSnapshotPrefix"
|
||||
ArmIsManagedImage string = "arm.IsManagedImage"
|
||||
ArmManagedImageResourceGroupName string = "arm.ManagedImageResourceGroupName"
|
||||
ArmManagedImageLocation string = "arm.ManagedImageLocation"
|
||||
ArmManagedImageName string = "arm.ManagedImageName"
|
||||
ArmManagedImageSigPublishResourceGroup string = "arm.ManagedImageSigPublishResourceGroup"
|
||||
ArmManagedImageSharedGalleryName string = "arm.ManagedImageSharedGalleryName"
|
||||
ArmManagedImageSharedGalleryImageName string = "arm.ManagedImageSharedGalleryImageName"
|
||||
ArmManagedImageSharedGalleryImageVersion string = "arm.ManagedImageSharedGalleryImageVersion"
|
||||
ArmManagedImageSharedGalleryReplicationRegions string = "arm.ManagedImageSharedGalleryReplicationRegions"
|
||||
ArmManagedImageSharedGalleryId string = "arm.ArmManagedImageSharedGalleryId"
|
||||
ArmManagedImageSharedGalleryImageVersionEndOfLifeDate string = "arm.ArmManagedImageSharedGalleryImageVersionEndOfLifeDate"
|
||||
ArmManagedImageSharedGalleryImageVersionReplicaCount string = "arm.ArmManagedImageSharedGalleryImageVersionReplicaCount"
|
||||
ArmManagedImageSharedGalleryImageVersionExcludeFromLatest string = "arm.ArmManagedImageSharedGalleryImageVersionExcludeFromLatest"
|
||||
ArmManagedImageSubscription string = "arm.ArmManagedImageSubscription"
|
||||
ArmAsyncResourceGroupDelete string = "arm.AsyncResourceGroupDelete"
|
||||
ArmManagedImageOSDiskSnapshotName string = "arm.ManagedImageOSDiskSnapshotName"
|
||||
ArmManagedImageDataDiskSnapshotPrefix string = "arm.ManagedImageDataDiskSnapshotPrefix"
|
||||
)
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
|
@ -15,20 +16,20 @@ const BuilderId = "packer.cloudstack"
|
|||
|
||||
// Builder represents the CloudStack builder.
|
||||
type Builder struct {
|
||||
config *Config
|
||||
config Config
|
||||
runner multistep.Runner
|
||||
ui packer.Ui
|
||||
}
|
||||
|
||||
// Prepare implements the packer.Builder interface.
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
config, errs := NewConfig(raws...)
|
||||
if errs != nil {
|
||||
return nil, errs
|
||||
}
|
||||
b.config = config
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
return nil, nil
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
errs := b.config.Prepare(raws...)
|
||||
if errs != nil {
|
||||
return nil, nil, errs
|
||||
}
|
||||
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
// Run implements the packer.Builder interface.
|
||||
|
@ -52,7 +53,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
// Set up the state.
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("client", client)
|
||||
state.Put("config", b.config)
|
||||
state.Put("config", &b.config)
|
||||
state.Put("hook", hook)
|
||||
state.Put("ui", ui)
|
||||
|
||||
|
@ -109,7 +110,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
// Build the artifact and return it
|
||||
artifact := &Artifact{
|
||||
client: client,
|
||||
config: b.config,
|
||||
config: &b.config,
|
||||
template: state.Get("template").(*cloudstack.CreateTemplateResponse),
|
||||
}
|
||||
|
||||
|
|
|
@ -40,10 +40,8 @@ func TestBuilder_Prepare(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
b := &Builder{}
|
||||
|
||||
for desc, tc := range cases {
|
||||
_, errs := b.Prepare(tc.Config)
|
||||
_, _, errs := (&Builder{}).Prepare(tc.Config)
|
||||
|
||||
if tc.Err {
|
||||
if errs == nil {
|
||||
|
|
|
@ -167,8 +167,7 @@ type Config struct {
|
|||
}
|
||||
|
||||
// NewConfig parses and validates the given config.
|
||||
func NewConfig(raws ...interface{}) (*Config, error) {
|
||||
c := new(Config)
|
||||
func (c *Config) Prepare(raws ...interface{}) error {
|
||||
err := config.Decode(c, &config.DecodeOpts{
|
||||
Interpolate: true,
|
||||
InterpolateContext: &c.ctx,
|
||||
|
@ -179,7 +178,7 @@ func NewConfig(raws ...interface{}) (*Config, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
var errs *packer.MultiError
|
||||
|
@ -309,8 +308,8 @@ func NewConfig(raws ...interface{}) (*Config, error) {
|
|||
|
||||
// Check for errors and return if we have any.
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, errs
|
||||
return errs
|
||||
}
|
||||
|
||||
return c, nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@ type FlatConfig struct {
|
|||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `cty:"ssh_private_key"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
|
@ -104,10 +104,13 @@ type FlatConfig struct {
|
|||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{} { return new(FlatConfig) }
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatConfig.
|
||||
// This spec is used by HCL to read the fields of FlatConfig.
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
|
|
|
@ -132,7 +132,8 @@ func TestNewConfig(t *testing.T) {
|
|||
raw[tc.Nullify] = nil
|
||||
}
|
||||
|
||||
_, errs := NewConfig(raw)
|
||||
var c Config
|
||||
errs := c.Prepare(raw)
|
||||
|
||||
if tc.Err {
|
||||
if errs == nil {
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"net/url"
|
||||
|
||||
"github.com/digitalocean/godo"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
|
@ -25,14 +26,15 @@ type Builder struct {
|
|||
runner multistep.Runner
|
||||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
c, warnings, errs := NewConfig(raws...)
|
||||
if errs != nil {
|
||||
return warnings, errs
|
||||
}
|
||||
b.config = *c
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
return nil, nil
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
warnings, errs := b.config.Prepare(raws...)
|
||||
if errs != nil {
|
||||
return nil, warnings, errs
|
||||
}
|
||||
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||
|
|
|
@ -32,7 +32,7 @@ func TestBuilder_Prepare_BadType(t *testing.T) {
|
|||
"api_key": []string{},
|
||||
}
|
||||
|
||||
warnings, err := b.Prepare(c)
|
||||
_, warnings, err := b.Prepare(c)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
|||
|
||||
// Add a random key
|
||||
config["i_should_not_be_valid"] = true
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ func TestBuilderPrepare_Region(t *testing.T) {
|
|||
|
||||
// Test default
|
||||
delete(config, "region")
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ func TestBuilderPrepare_Region(t *testing.T) {
|
|||
// Test set
|
||||
config["region"] = expected
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ func TestBuilderPrepare_Size(t *testing.T) {
|
|||
|
||||
// Test default
|
||||
delete(config, "size")
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ func TestBuilderPrepare_Size(t *testing.T) {
|
|||
// Test set
|
||||
config["size"] = expected
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ func TestBuilderPrepare_Image(t *testing.T) {
|
|||
|
||||
// Test default
|
||||
delete(config, "image")
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ func TestBuilderPrepare_Image(t *testing.T) {
|
|||
// Test set
|
||||
config["image"] = expected
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ func TestBuilderPrepare_StateTimeout(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
// Test default
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ func TestBuilderPrepare_StateTimeout(t *testing.T) {
|
|||
// Test set
|
||||
config["state_timeout"] = "5m"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ func TestBuilderPrepare_StateTimeout(t *testing.T) {
|
|||
// Test bad
|
||||
config["state_timeout"] = "tubes"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ func TestBuilderPrepare_SnapshotTimeout(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
// Test default
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ func TestBuilderPrepare_SnapshotTimeout(t *testing.T) {
|
|||
// Test set
|
||||
config["snapshot_timeout"] = "15m"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ func TestBuilderPrepare_SnapshotTimeout(t *testing.T) {
|
|||
// Test bad
|
||||
config["snapshot_timeout"] = "badstring"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ func TestBuilderPrepare_PrivateNetworking(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
// Test default
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ func TestBuilderPrepare_PrivateNetworking(t *testing.T) {
|
|||
// Test set
|
||||
config["private_networking"] = true
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ func TestBuilderPrepare_SnapshotName(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
// Test default
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ func TestBuilderPrepare_SnapshotName(t *testing.T) {
|
|||
// Test set
|
||||
config["snapshot_name"] = "foobarbaz"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ func TestBuilderPrepare_SnapshotName(t *testing.T) {
|
|||
// Test set with template
|
||||
config["snapshot_name"] = "{{timestamp}}"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ func TestBuilderPrepare_DropletName(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
// Test default
|
||||
warnings, err := b.Prepare(config)
|
||||
_, warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ func TestBuilderPrepare_DropletName(t *testing.T) {
|
|||
// Test normal set
|
||||
config["droplet_name"] = "foobar"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -342,7 +342,7 @@ func TestBuilderPrepare_DropletName(t *testing.T) {
|
|||
// Test with template
|
||||
config["droplet_name"] = "foobar-{{timestamp}}"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
@ -353,7 +353,7 @@ func TestBuilderPrepare_DropletName(t *testing.T) {
|
|||
// Test with bad template
|
||||
config["droplet_name"] = "foobar-{{"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
_, warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
|
|
|
@ -89,8 +89,7 @@ type Config struct {
|
|||
ctx interpolate.Context
|
||||
}
|
||||
|
||||
func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
||||
c := new(Config)
|
||||
func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
||||
|
||||
var md mapstructure.Metadata
|
||||
err := config.Decode(c, &config.DecodeOpts{
|
||||
|
@ -104,7 +103,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Defaults
|
||||
|
@ -189,9 +188,9 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, nil, errs
|
||||
return nil, errs
|
||||
}
|
||||
|
||||
packer.LogSecretFilter.Set(c.APIToken)
|
||||
return c, nil, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@ type FlatConfig struct {
|
|||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `cty:"ssh_private_key"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
|
@ -77,10 +77,13 @@ type FlatConfig struct {
|
|||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{} { return new(FlatConfig) }
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatConfig.
|
||||
// This spec is used by HCL to read the fields of FlatConfig.
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
|
|
|
@ -63,6 +63,9 @@ func (s *stepCreateDroplet) Run(ctx context.Context, state multistep.StateBag) m
|
|||
|
||||
// Store the droplet id for later
|
||||
state.Put("droplet_id", droplet.ID)
|
||||
// instance_id is the generic term used so that users can have access to the
|
||||
// instance id inside of the provisioners, used in step_provision.
|
||||
state.Put("instance_id", droplet.ID)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
|
@ -16,18 +17,19 @@ const (
|
|||
)
|
||||
|
||||
type Builder struct {
|
||||
config *Config
|
||||
config Config
|
||||
runner multistep.Runner
|
||||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
c, warnings, errs := NewConfig(raws...)
|
||||
if errs != nil {
|
||||
return warnings, errs
|
||||
}
|
||||
b.config = c
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
return warnings, nil
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
warnings, errs := b.config.Prepare(raws...)
|
||||
if errs != nil {
|
||||
return nil, warnings, errs
|
||||
}
|
||||
|
||||
return nil, warnings, nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||
|
@ -75,7 +77,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
|
||||
// Setup the state bag and initial state for the steps
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("config", b.config)
|
||||
state.Put("config", &b.config)
|
||||
state.Put("hook", hook)
|
||||
state.Put("ui", ui)
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ func TestUploadDownload(t *testing.T) {
|
|||
|
||||
// Setup the builder
|
||||
builder := &Builder{}
|
||||
warnings, err := builder.Prepare(tpl.Builders["docker"].Config)
|
||||
_, warnings, err := builder.Prepare(tpl.Builders["docker"].Config)
|
||||
if err != nil {
|
||||
t.Fatalf("Error preparing configuration %s", err)
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ func TestLargeDownload(t *testing.T) {
|
|||
|
||||
// Setup the builder
|
||||
builder := &Builder{}
|
||||
warnings, err := builder.Prepare(tpl.Builders["docker"].Config)
|
||||
_, warnings, err := builder.Prepare(tpl.Builders["docker"].Config)
|
||||
if err != nil {
|
||||
t.Fatalf("Error preparing configuration %s", err)
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ func TestFixUploadOwner(t *testing.T) {
|
|||
|
||||
// Setup the builder
|
||||
builder := &Builder{}
|
||||
warnings, err := builder.Prepare(tpl.Builders["docker"].Config)
|
||||
_, warnings, err := builder.Prepare(tpl.Builders["docker"].Config)
|
||||
if err != nil {
|
||||
t.Fatalf("Error preparing configuration %s", err)
|
||||
}
|
||||
|
|
|
@ -107,8 +107,7 @@ type Config struct {
|
|||
ctx interpolate.Context
|
||||
}
|
||||
|
||||
func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
||||
c := new(Config)
|
||||
func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
||||
|
||||
c.FixUploadOwner = true
|
||||
|
||||
|
@ -124,7 +123,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Defaults
|
||||
|
@ -191,8 +190,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, nil, errs
|
||||
return nil, errs
|
||||
}
|
||||
|
||||
return c, nil, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@ type FlatConfig struct {
|
|||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `cty:"ssh_private_key"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
|
@ -86,10 +86,13 @@ type FlatConfig struct {
|
|||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{} { return new(FlatConfig) }
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatConfig.
|
||||
// This spec is used by HCL to read the fields of FlatConfig.
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
|
|
|
@ -14,7 +14,8 @@ func testConfig() map[string]interface{} {
|
|||
}
|
||||
|
||||
func testConfigStruct(t *testing.T) *Config {
|
||||
c, warns, errs := NewConfig(testConfig())
|
||||
var c Config
|
||||
warns, errs := c.Prepare(testConfig())
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", len(warns))
|
||||
}
|
||||
|
@ -22,7 +23,7 @@ func testConfigStruct(t *testing.T) *Config {
|
|||
t.Fatalf("bad: %#v", errs)
|
||||
}
|
||||
|
||||
return c
|
||||
return &c
|
||||
}
|
||||
|
||||
func testConfigErr(t *testing.T, warns []string, err error) {
|
||||
|
@ -55,17 +56,18 @@ func TestConfigPrepare_exportPath(t *testing.T) {
|
|||
// No export path. This is invalid. Previously this would not error during
|
||||
// validation and as a result the failure would happen at build time.
|
||||
delete(raw, "export_path")
|
||||
_, warns, errs := NewConfig(raw)
|
||||
var c Config
|
||||
warns, errs := c.Prepare(raw)
|
||||
testConfigErr(t, warns, errs)
|
||||
|
||||
// Good export path
|
||||
raw["export_path"] = "good"
|
||||
_, warns, errs = NewConfig(raw)
|
||||
warns, errs = c.Prepare(raw)
|
||||
testConfigOk(t, warns, errs)
|
||||
|
||||
// Bad export path (directory)
|
||||
raw["export_path"] = td
|
||||
_, warns, errs = NewConfig(raw)
|
||||
warns, errs = c.Prepare(raw)
|
||||
testConfigErr(t, warns, errs)
|
||||
}
|
||||
|
||||
|
@ -74,17 +76,17 @@ func TestConfigPrepare_exportPathAndCommit(t *testing.T) {
|
|||
|
||||
// Export but no commit (explicit default)
|
||||
raw["commit"] = false
|
||||
_, warns, errs := NewConfig(raw)
|
||||
warns, errs := (&Config{}).Prepare(raw)
|
||||
testConfigOk(t, warns, errs)
|
||||
|
||||
// Commit AND export specified (invalid)
|
||||
raw["commit"] = true
|
||||
_, warns, errs = NewConfig(raw)
|
||||
warns, errs = (&Config{}).Prepare(raw)
|
||||
testConfigErr(t, warns, errs)
|
||||
|
||||
// Commit but no export
|
||||
delete(raw, "export_path")
|
||||
_, warns, errs = NewConfig(raw)
|
||||
warns, errs = (&Config{}).Prepare(raw)
|
||||
testConfigOk(t, warns, errs)
|
||||
}
|
||||
|
||||
|
@ -93,18 +95,18 @@ func TestConfigPrepare_exportDiscard(t *testing.T) {
|
|||
|
||||
// Export but no discard (explicit default)
|
||||
raw["discard"] = false
|
||||
_, warns, errs := NewConfig(raw)
|
||||
warns, errs := (&Config{}).Prepare(raw)
|
||||
testConfigOk(t, warns, errs)
|
||||
|
||||
// Discard AND export (invalid)
|
||||
raw["discard"] = true
|
||||
_, warns, errs = NewConfig(raw)
|
||||
warns, errs = (&Config{}).Prepare(raw)
|
||||
testConfigErr(t, warns, errs)
|
||||
|
||||
// Discard but no export
|
||||
raw["discard"] = true
|
||||
delete(raw, "export_path")
|
||||
_, warns, errs = NewConfig(raw)
|
||||
warns, errs = (&Config{}).Prepare(raw)
|
||||
testConfigOk(t, warns, errs)
|
||||
}
|
||||
|
||||
|
@ -113,12 +115,13 @@ func TestConfigPrepare_image(t *testing.T) {
|
|||
|
||||
// No image
|
||||
delete(raw, "image")
|
||||
_, warns, errs := NewConfig(raw)
|
||||
var c Config
|
||||
warns, errs := c.Prepare(raw)
|
||||
testConfigErr(t, warns, errs)
|
||||
|
||||
// Good image
|
||||
raw["image"] = "path"
|
||||
_, warns, errs = NewConfig(raw)
|
||||
warns, errs = c.Prepare(raw)
|
||||
testConfigOk(t, warns, errs)
|
||||
}
|
||||
|
||||
|
@ -127,7 +130,8 @@ func TestConfigPrepare_pull(t *testing.T) {
|
|||
|
||||
// No pull set
|
||||
delete(raw, "pull")
|
||||
c, warns, errs := NewConfig(raw)
|
||||
var c Config
|
||||
warns, errs := c.Prepare(raw)
|
||||
testConfigOk(t, warns, errs)
|
||||
if !c.Pull {
|
||||
t.Fatal("should pull by default")
|
||||
|
@ -135,7 +139,7 @@ func TestConfigPrepare_pull(t *testing.T) {
|
|||
|
||||
// Pull set
|
||||
raw["pull"] = false
|
||||
c, warns, errs = NewConfig(raw)
|
||||
warns, errs = c.Prepare(raw)
|
||||
testConfigOk(t, warns, errs)
|
||||
if c.Pull {
|
||||
t.Fatal("should not pull")
|
||||
|
|
|
@ -14,11 +14,17 @@ type StepCommit struct {
|
|||
}
|
||||
|
||||
func (s *StepCommit) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
config, ok := state.Get("config").(*Config)
|
||||
if !ok {
|
||||
err := fmt.Errorf("error encountered obtaining docker config")
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(Driver)
|
||||
containerId := state.Get("container_id").(string)
|
||||
config := state.Get("config").(*Config)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
if config.WindowsContainer {
|
||||
// docker can't commit a running Windows container
|
||||
err := driver.StopContainer(containerId)
|
||||
|
|
|
@ -12,7 +12,13 @@ import (
|
|||
type StepConnectDocker struct{}
|
||||
|
||||
func (s *StepConnectDocker) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(*Config)
|
||||
config, ok := state.Get("config").(*Config)
|
||||
if !ok {
|
||||
err := fmt.Errorf("error encountered obtaining docker config")
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
containerId := state.Get("container_id").(string)
|
||||
driver := state.Get("driver").(Driver)
|
||||
tempDir := state.Get("temp_dir").(string)
|
||||
|
|
|
@ -14,11 +14,14 @@ import (
|
|||
type StepExport struct{}
|
||||
|
||||
func (s *StepExport) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(*Config)
|
||||
|
||||
driver := state.Get("driver").(Driver)
|
||||
containerId := state.Get("container_id").(string)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
config, ok := state.Get("config").(*Config)
|
||||
if !ok {
|
||||
err := fmt.Errorf("error encountered obtaining docker config")
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
// We should catch this in validation, but guard anyway
|
||||
if config.ExportPath == "" {
|
||||
|
@ -44,6 +47,9 @@ func (s *StepExport) Run(ctx context.Context, state multistep.StateBag) multiste
|
|||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(Driver)
|
||||
containerId := state.Get("container_id").(string)
|
||||
|
||||
ui.Say("Exporting the container")
|
||||
if err := driver.Export(containerId, f); err != nil {
|
||||
f.Close()
|
||||
|
|
|
@ -12,9 +12,14 @@ import (
|
|||
type StepPull struct{}
|
||||
|
||||
func (s *StepPull) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(*Config)
|
||||
driver := state.Get("driver").(Driver)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
config, ok := state.Get("config").(*Config)
|
||||
if !ok {
|
||||
err := fmt.Errorf("error encountered obtaining docker config")
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
if !config.Pull {
|
||||
log.Println("Pull disabled, won't docker pull")
|
||||
|
@ -38,6 +43,7 @@ func (s *StepPull) Run(ctx context.Context, state multistep.StateBag) multistep.
|
|||
config.LoginPassword = password
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(Driver)
|
||||
if config.Login || config.EcrLogin {
|
||||
ui.Message("Logging in...")
|
||||
err := driver.Login(
|
||||
|
|
|
@ -13,10 +13,14 @@ type StepRun struct {
|
|||
}
|
||||
|
||||
func (s *StepRun) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(*Config)
|
||||
driver := state.Get("driver").(Driver)
|
||||
tempDir := state.Get("temp_dir").(string)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
config, ok := state.Get("config").(*Config)
|
||||
if !ok {
|
||||
err := fmt.Errorf("error encountered obtaining docker config")
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
runConfig := ContainerConfig{
|
||||
Image: config.Image,
|
||||
|
@ -28,8 +32,11 @@ func (s *StepRun) Run(ctx context.Context, state multistep.StateBag) multistep.S
|
|||
for host, container := range config.Volumes {
|
||||
runConfig.Volumes[host] = container
|
||||
}
|
||||
|
||||
tempDir := state.Get("temp_dir").(string)
|
||||
runConfig.Volumes[tempDir] = config.ContainerDir
|
||||
|
||||
driver := state.Get("driver").(Driver)
|
||||
ui.Say("Starting docker container...")
|
||||
containerId, err := driver.StartContainer(&runConfig)
|
||||
if err != nil {
|
||||
|
@ -42,6 +49,9 @@ func (s *StepRun) Run(ctx context.Context, state multistep.StateBag) multistep.S
|
|||
// Save the container ID
|
||||
s.containerId = containerId
|
||||
state.Put("container_id", s.containerId)
|
||||
// instance_id is the generic term used so that users can have access to the
|
||||
// instance id inside of the provisioners, used in step_provision.
|
||||
state.Put("instance_id", s.containerId)
|
||||
ui.Message(fmt.Sprintf("Container ID: %s", s.containerId))
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
@ -19,18 +20,19 @@ import (
|
|||
const BuilderId = "packer.file"
|
||||
|
||||
type Builder struct {
|
||||
config *Config
|
||||
config Config
|
||||
runner multistep.Runner
|
||||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
c, warnings, errs := NewConfig(raws...)
|
||||
if errs != nil {
|
||||
return warnings, errs
|
||||
}
|
||||
b.config = c
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
return warnings, nil
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
warnings, errs := b.config.Prepare(raws...)
|
||||
if errs != nil {
|
||||
return nil, warnings, errs
|
||||
}
|
||||
|
||||
return nil, warnings, nil
|
||||
}
|
||||
|
||||
// Run is where the actual build should take place. It takes a Build and a Ui.
|
||||
|
|
|
@ -22,8 +22,7 @@ type Config struct {
|
|||
Content string `mapstructure:"content"`
|
||||
}
|
||||
|
||||
func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
||||
c := new(Config)
|
||||
func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
||||
warnings := []string{}
|
||||
|
||||
err := config.Decode(c, &config.DecodeOpts{
|
||||
|
@ -33,7 +32,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, warnings, err
|
||||
return warnings, err
|
||||
}
|
||||
|
||||
var errs *packer.MultiError
|
||||
|
@ -51,8 +50,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, warnings, errs
|
||||
return warnings, errs
|
||||
}
|
||||
|
||||
return c, warnings, nil
|
||||
return warnings, nil
|
||||
}
|
||||
|
|
|
@ -24,10 +24,13 @@ type FlatConfig struct {
|
|||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{} { return new(FlatConfig) }
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatConfig.
|
||||
// This spec is used by HCL to read the fields of FlatConfig.
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
|
|
|
@ -16,7 +16,8 @@ func testConfig() map[string]interface{} {
|
|||
func TestContentSourceConflict(t *testing.T) {
|
||||
raw := testConfig()
|
||||
|
||||
_, _, errs := NewConfig(raw)
|
||||
var c Config
|
||||
_, errs := c.Prepare(raw)
|
||||
if !strings.Contains(errs.Error(), ErrContentSourceConflict.Error()) {
|
||||
t.Errorf("Expected config error: %s", ErrContentSourceConflict.Error())
|
||||
}
|
||||
|
@ -26,7 +27,8 @@ func TestNoFilename(t *testing.T) {
|
|||
raw := testConfig()
|
||||
|
||||
delete(raw, "filename")
|
||||
_, _, errs := NewConfig(raw)
|
||||
var c Config
|
||||
_, errs := c.Prepare(raw)
|
||||
if errs == nil {
|
||||
t.Errorf("Expected config error: %s", ErrTargetRequired.Error())
|
||||
}
|
||||
|
@ -37,7 +39,8 @@ func TestNoContent(t *testing.T) {
|
|||
|
||||
delete(raw, "content")
|
||||
delete(raw, "source")
|
||||
_, warns, _ := NewConfig(raw)
|
||||
var c Config
|
||||
warns, _ := c.Prepare(raw)
|
||||
|
||||
if len(warns) == 0 {
|
||||
t.Error("Expected config warning without any content")
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
|
@ -18,18 +19,18 @@ const BuilderId = "packer.googlecompute"
|
|||
|
||||
// Builder represents a Packer Builder.
|
||||
type Builder struct {
|
||||
config *Config
|
||||
config Config
|
||||
runner multistep.Runner
|
||||
}
|
||||
|
||||
// Prepare processes the build configuration parameters.
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
c, warnings, errs := NewConfig(raws...)
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
warnings, errs := b.config.Prepare(raws...)
|
||||
if errs != nil {
|
||||
return warnings, errs
|
||||
return nil, warnings, errs
|
||||
}
|
||||
b.config = c
|
||||
return warnings, nil
|
||||
return nil, warnings, nil
|
||||
}
|
||||
|
||||
// Run executes a googlecompute Packer build and returns a packer.Artifact
|
||||
|
@ -43,7 +44,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
|
||||
// Set up the state.
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("config", b.config)
|
||||
state.Put("config", &b.config)
|
||||
state.Put("driver", driver)
|
||||
state.Put("hook", hook)
|
||||
state.Put("ui", ui)
|
||||
|
@ -97,7 +98,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
artifact := &Artifact{
|
||||
image: state.Get("image").(*Image),
|
||||
driver: driver,
|
||||
config: b.config,
|
||||
config: &b.config,
|
||||
}
|
||||
return artifact, nil
|
||||
}
|
||||
|
|
|
@ -187,8 +187,7 @@ type Config struct {
|
|||
ctx interpolate.Context
|
||||
}
|
||||
|
||||
func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
||||
c := new(Config)
|
||||
func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
||||
c.ctx.Funcs = TemplateFuncs
|
||||
err := config.Decode(c, &config.DecodeOpts{
|
||||
Interpolate: true,
|
||||
|
@ -200,7 +199,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var errs *packer.MultiError
|
||||
|
@ -372,10 +371,10 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
|
||||
// Check for any errors.
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, nil, errs
|
||||
return nil, errs
|
||||
}
|
||||
|
||||
return c, nil, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type CustomerEncryptionKey struct {
|
||||
|
|
|
@ -46,8 +46,8 @@ type FlatConfig struct {
|
|||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `cty:"ssh_private_key"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
|
@ -100,10 +100,13 @@ type FlatConfig struct {
|
|||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{} { return new(FlatConfig) }
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatConfig.
|
||||
// This spec is used by HCL to read the fields of FlatConfig.
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
|
@ -206,10 +209,13 @@ type FlatCustomerEncryptionKey struct {
|
|||
// FlatMapstructure returns a new FlatCustomerEncryptionKey.
|
||||
// FlatCustomerEncryptionKey is an auto-generated flat version of CustomerEncryptionKey.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*CustomerEncryptionKey) FlatMapstructure() interface{} { return new(FlatCustomerEncryptionKey) }
|
||||
func (*CustomerEncryptionKey) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatCustomerEncryptionKey)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatCustomerEncryptionKey.
|
||||
// This spec is used by HCL to read the fields of FlatCustomerEncryptionKey.
|
||||
// HCL2Spec returns the hcl spec of a CustomerEncryptionKey.
|
||||
// This spec is used by HCL to read the fields of CustomerEncryptionKey.
|
||||
// The decoded values from this spec will then be applied to a FlatCustomerEncryptionKey.
|
||||
func (*FlatCustomerEncryptionKey) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"kms_key_name": &hcldec.AttrSpec{Name: "kms_key_name", Type: cty.String, Required: false},
|
||||
|
|
|
@ -242,7 +242,8 @@ func TestConfigPrepare(t *testing.T) {
|
|||
raw[tc.Key] = tc.Value
|
||||
}
|
||||
|
||||
_, warns, errs := NewConfig(raw)
|
||||
var c Config
|
||||
warns, errs := c.Prepare(raw)
|
||||
|
||||
if tc.Err {
|
||||
testConfigErr(t, warns, errs, tc.Key)
|
||||
|
@ -302,7 +303,8 @@ func TestConfigPrepareAccelerator(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
_, warns, errs := NewConfig(raw)
|
||||
var c Config
|
||||
warns, errs := c.Prepare(raw)
|
||||
|
||||
if tc.Err {
|
||||
testConfigErr(t, warns, errs, strings.TrimRight(errStr, ", "))
|
||||
|
@ -352,7 +354,8 @@ func TestConfigPrepareServiceAccount(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
_, warns, errs := NewConfig(raw)
|
||||
var c Config
|
||||
warns, errs := c.Prepare(raw)
|
||||
|
||||
if tc.Err {
|
||||
testConfigErr(t, warns, errs, strings.TrimRight(errStr, ", "))
|
||||
|
@ -371,7 +374,8 @@ func TestConfigPrepareStartupScriptFile(t *testing.T) {
|
|||
"zone": "us-central1-a",
|
||||
}
|
||||
|
||||
_, _, errs := NewConfig(config)
|
||||
var c Config
|
||||
_, errs := c.Prepare(config)
|
||||
|
||||
if errs == nil || !strings.Contains(errs.Error(), "startup_script_file") {
|
||||
t.Fatalf("should error: startup_script_file")
|
||||
|
@ -398,10 +402,11 @@ func TestConfigDefaults(t *testing.T) {
|
|||
raw, tempfile := testConfig(t)
|
||||
defer os.Remove(tempfile)
|
||||
|
||||
c, warns, errs := NewConfig(raw)
|
||||
var c Config
|
||||
warns, errs := c.Prepare(raw)
|
||||
testConfigOk(t, warns, errs)
|
||||
|
||||
actual := tc.Read(c)
|
||||
actual := tc.Read(&c)
|
||||
if actual != tc.Value {
|
||||
t.Fatalf("bad: %#v", actual)
|
||||
}
|
||||
|
@ -412,7 +417,8 @@ func TestImageName(t *testing.T) {
|
|||
raw, tempfile := testConfig(t)
|
||||
defer os.Remove(tempfile)
|
||||
|
||||
c, _, _ := NewConfig(raw)
|
||||
var c Config
|
||||
c.Prepare(raw)
|
||||
if !strings.HasPrefix(c.ImageName, "packer-") {
|
||||
t.Fatalf("ImageName should have 'packer-' prefix, found %s", c.ImageName)
|
||||
}
|
||||
|
@ -425,7 +431,8 @@ func TestRegion(t *testing.T) {
|
|||
raw, tempfile := testConfig(t)
|
||||
defer os.Remove(tempfile)
|
||||
|
||||
c, _, _ := NewConfig(raw)
|
||||
var c Config
|
||||
c.Prepare(raw)
|
||||
if c.Region != "us-east1" {
|
||||
t.Fatalf("Region should be 'us-east1' given Zone of 'us-east1-a', but is %s", c.Region)
|
||||
}
|
||||
|
@ -460,7 +467,8 @@ func testConfigStruct(t *testing.T) *Config {
|
|||
raw, tempfile := testConfig(t)
|
||||
defer os.Remove(tempfile)
|
||||
|
||||
c, warns, errs := NewConfig(raw)
|
||||
var c Config
|
||||
warns, errs := c.Prepare(raw)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", len(warns))
|
||||
}
|
||||
|
@ -468,7 +476,7 @@ func testConfigStruct(t *testing.T) *Config {
|
|||
t.Fatalf("bad: %#v", errs)
|
||||
}
|
||||
|
||||
return c
|
||||
return &c
|
||||
}
|
||||
|
||||
func testConfigErr(t *testing.T, warns []string, err error, extra string) {
|
||||
|
|
|
@ -176,6 +176,9 @@ func (s *StepCreateInstance) Run(ctx context.Context, state multistep.StateBag)
|
|||
|
||||
// Things succeeded, store the name so we can remove it later
|
||||
state.Put("instance_name", name)
|
||||
// instance_id is the generic term used so that users can have access to the
|
||||
// instance id inside of the provisioners, used in step_provision.
|
||||
state.Put("instance_id", name)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
commonhelper "github.com/hashicorp/packer/helper/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
@ -119,7 +118,6 @@ func (s *StepCreateWindowsPassword) Run(ctx context.Context, state multistep.Sta
|
|||
}
|
||||
|
||||
state.Put("winrm_password", data.password)
|
||||
commonhelper.SetSharedState("winrm_password", data.password, c.PackerConfig.PackerBuildName)
|
||||
packer.LogSecretFilter.Set(data.password)
|
||||
|
||||
return multistep.ActionContinue
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
|
@ -22,13 +23,15 @@ type Builder struct {
|
|||
|
||||
var pluginVersion = "1.0.0"
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
config, warnings, errs := NewConfig(raws...)
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
warnings, errs := b.config.Prepare(raws...)
|
||||
if errs != nil {
|
||||
return warnings, errs
|
||||
return nil, warnings, errs
|
||||
}
|
||||
b.config = *config
|
||||
return nil, nil
|
||||
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||
|
|
|
@ -50,9 +50,7 @@ type imageFilter struct {
|
|||
MostRecent bool `mapstructure:"most_recent"`
|
||||
}
|
||||
|
||||
func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
||||
c := new(Config)
|
||||
|
||||
func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
||||
var md mapstructure.Metadata
|
||||
err := config.Decode(c, &config.DecodeOpts{
|
||||
Metadata: &md,
|
||||
|
@ -65,7 +63,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Defaults
|
||||
|
@ -142,11 +140,11 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, nil, errs
|
||||
return nil, errs
|
||||
}
|
||||
|
||||
packer.LogSecretFilter.Set(c.HCloudToken)
|
||||
return c, nil, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func getServerIP(state multistep.StateBag) (string, error) {
|
||||
|
|
|
@ -46,8 +46,8 @@ type FlatConfig struct {
|
|||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `cty:"ssh_private_key"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
|
@ -75,10 +75,13 @@ type FlatConfig struct {
|
|||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{} { return new(FlatConfig) }
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatConfig.
|
||||
// This spec is used by HCL to read the fields of FlatConfig.
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
|
@ -156,10 +159,13 @@ type FlatimageFilter struct {
|
|||
// FlatMapstructure returns a new FlatimageFilter.
|
||||
// FlatimageFilter is an auto-generated flat version of imageFilter.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*imageFilter) FlatMapstructure() interface{} { return new(FlatimageFilter) }
|
||||
func (*imageFilter) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatimageFilter)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatimageFilter.
|
||||
// This spec is used by HCL to read the fields of FlatimageFilter.
|
||||
// HCL2Spec returns the hcl spec of a imageFilter.
|
||||
// This spec is used by HCL to read the fields of imageFilter.
|
||||
// The decoded values from this spec will then be applied to a FlatimageFilter.
|
||||
func (*FlatimageFilter) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"with_selector": &hcldec.AttrSpec{Name: "with_selector", Type: cty.List(cty.String), Required: false},
|
||||
|
|
|
@ -85,6 +85,9 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu
|
|||
|
||||
// Store the server id for later
|
||||
state.Put("server_id", serverCreateResult.Server.ID)
|
||||
// instance_id is the generic term used so that users can have access to the
|
||||
// instance id inside of the provisioners, used in step_provision.
|
||||
state.Put("instance_id", serverCreateResult.Server.ID)
|
||||
|
||||
if err := waitForAction(ctx, client, serverCreateResult.Action); err != nil {
|
||||
err := fmt.Errorf("Error creating server: %s", err)
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
|
@ -20,13 +21,13 @@ type Builder struct {
|
|||
client *openapi.APIClient
|
||||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
config, warnings, errs := NewConfig(raws...)
|
||||
if errs != nil {
|
||||
return warnings, errs
|
||||
}
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
b.config = *config
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
warnings, errs := b.config.Prepare(raws...)
|
||||
if errs != nil {
|
||||
return nil, warnings, errs
|
||||
}
|
||||
|
||||
cfg := openapi.NewConfiguration()
|
||||
cfg.AddDefaultHeader("x-auth-token", b.config.Token)
|
||||
|
@ -43,7 +44,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
|
||||
b.client = openapi.NewAPIClient(cfg)
|
||||
|
||||
return nil, nil
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
type wrappedCommandTemplate struct {
|
||||
|
|
|
@ -114,8 +114,7 @@ type Config struct {
|
|||
ctx interpolate.Context
|
||||
}
|
||||
|
||||
func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
||||
c := &Config{}
|
||||
func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
||||
|
||||
var md mapstructure.Metadata
|
||||
err := config.Decode(c, &config.DecodeOpts{
|
||||
|
@ -133,12 +132,12 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cliConfig, err := loadCLIConfig()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Defaults
|
||||
|
@ -165,7 +164,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
if c.TokenLogin != "" && c.APIURL == "" {
|
||||
c.Token, err = fetchTokenBySSH(c.TokenLogin)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +180,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
if c.ImageName == "" {
|
||||
name, err := interpolate.Render("packer-{{timestamp}}", nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
c.ImageName = name
|
||||
}
|
||||
|
@ -217,7 +216,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
if c.ChrootMountPath == "" {
|
||||
path, err := interpolate.Render("/mnt/packer-hyperone-volumes/{{timestamp}}", nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
c.ChrootMountPath = path
|
||||
}
|
||||
|
@ -281,12 +280,12 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, nil, errs
|
||||
return nil, errs
|
||||
}
|
||||
|
||||
packer.LogSecretFilter.Set(c.Token)
|
||||
|
||||
return c, nil, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type cliConfig struct {
|
||||
|
|
|
@ -46,8 +46,8 @@ type FlatConfig struct {
|
|||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `cty:"ssh_private_key"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
|
@ -94,10 +94,13 @@ type FlatConfig struct {
|
|||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{} { return new(FlatConfig) }
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatConfig.
|
||||
// This spec is used by HCL to read the fields of FlatConfig.
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
|
|
|
@ -67,6 +67,9 @@ func (s *stepCreateVM) Run(ctx context.Context, state multistep.StateBag) multis
|
|||
|
||||
s.vmID = vm.Id
|
||||
state.Put("vm_id", vm.Id)
|
||||
// instance_id is the generic term used so that users can have access to the
|
||||
// instance id inside of the provisioners, used in step_provision.
|
||||
state.Put("instance_id", vm.Id)
|
||||
|
||||
hdds, _, err := client.VmApi.VmListHdd(ctx, vm.Id)
|
||||
if err != nil {
|
||||
|
|
|
@ -15,10 +15,13 @@ type FlatOutputConfig struct {
|
|||
// FlatMapstructure returns a new FlatOutputConfig.
|
||||
// FlatOutputConfig is an auto-generated flat version of OutputConfig.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*OutputConfig) FlatMapstructure() interface{} { return new(FlatOutputConfig) }
|
||||
func (*OutputConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatOutputConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatOutputConfig.
|
||||
// This spec is used by HCL to read the fields of FlatOutputConfig.
|
||||
// HCL2Spec returns the hcl spec of a OutputConfig.
|
||||
// This spec is used by HCL to read the fields of OutputConfig.
|
||||
// The decoded values from this spec will then be applied to a FlatOutputConfig.
|
||||
func (*FlatOutputConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false},
|
||||
|
|
|
@ -154,6 +154,9 @@ func (s *StepCloneVM) Run(ctx context.Context, state multistep.StateBag) multist
|
|||
|
||||
// Set the final name in the state bag so others can use it
|
||||
state.Put("vmName", s.VMName)
|
||||
// instance_id is the generic term used so that users can have access to the
|
||||
// instance id inside of the provisioners, used in step_provision.
|
||||
state.Put("instance_id", s.VMName)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -166,6 +166,9 @@ func (s *StepCreateVM) Run(ctx context.Context, state multistep.StateBag) multis
|
|||
|
||||
// Set the final name in the state bag so others can use it
|
||||
state.Put("vmName", s.VMName)
|
||||
// instance_id is the generic term used so that users can have access to the
|
||||
// instance id inside of the provisioners, used in step_provision.
|
||||
state.Put("instance_id", s.VMName)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
hypervcommon "github.com/hashicorp/packer/builder/hyperv/common"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/common/bootcommand"
|
||||
|
@ -84,8 +85,9 @@ type Config struct {
|
|||
ctx interpolate.Context
|
||||
}
|
||||
|
||||
// Prepare processes the build configuration parameters.
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
err := config.Decode(&b.config, &config.DecodeOpts{
|
||||
Interpolate: true,
|
||||
InterpolateContext: &b.config.ctx,
|
||||
|
@ -96,7 +98,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Accumulate any errors and warnings
|
||||
|
@ -164,10 +166,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return warnings, errs
|
||||
return nil, warnings, errs
|
||||
}
|
||||
|
||||
return warnings, nil
|
||||
return nil, warnings, nil
|
||||
}
|
||||
|
||||
// Run executes a Packer build and returns a packer.Artifact representing
|
||||
|
@ -181,7 +183,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
|
||||
// Set up the state.
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("config", &b.config)
|
||||
state.Put("debug", b.config.PackerDebug)
|
||||
state.Put("driver", driver)
|
||||
state.Put("hook", hook)
|
||||
|
|
|
@ -60,8 +60,8 @@ type FlatConfig struct {
|
|||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `cty:"ssh_private_key"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||
|
@ -108,10 +108,13 @@ type FlatConfig struct {
|
|||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{} { return new(FlatConfig) }
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcldec.Spec of a FlatConfig.
|
||||
// This spec is used by HCL to read the fields of FlatConfig.
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
|
|
|
@ -42,7 +42,7 @@ func TestBuilderPrepare_Defaults(t *testing.T) {
|
|||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ func TestBuilderPrepare_DiskSize(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
delete(config, "disk_size")
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ func TestBuilderPrepare_DiskSize(t *testing.T) {
|
|||
|
||||
config["disk_size"] = 256
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ func TestBuilderPrepare_DiskBlockSize(t *testing.T) {
|
|||
|
||||
// Test default with empty disk_block_size
|
||||
delete(config, "disk_block_size")
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ func TestBuilderPrepare_DiskBlockSize(t *testing.T) {
|
|||
for _, test_size := range test_sizes {
|
||||
config["disk_block_size"] = test_size
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if test_size > expected_max_block_size || test_size < expected_min_block_size {
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad, should have no warns: %#v", warns)
|
||||
|
@ -153,7 +153,7 @@ func TestBuilderPrepare_FixedVHDFormat(t *testing.T) {
|
|||
|
||||
// use_fixed_vhd_format should work with generation = 1, skip_compaction
|
||||
// = true, and differencing_disk = false
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ func TestBuilderPrepare_FixedVHDFormat(t *testing.T) {
|
|||
//use_fixed_vhd_format should not work with differencing_disk = true
|
||||
config["differencing_disk"] = true
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ func TestBuilderPrepare_FixedVHDFormat(t *testing.T) {
|
|||
//use_fixed_vhd_format should not work with skip_compaction = false
|
||||
config["skip_compaction"] = false
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ func TestBuilderPrepare_FixedVHDFormat(t *testing.T) {
|
|||
//use_fixed_vhd_format should not work with generation = 2
|
||||
config["generation"] = 2
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ func TestBuilderPrepare_FloppyFiles(t *testing.T) {
|
|||
config := testConfig()
|
||||
|
||||
delete(config, "floppy_files")
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ func TestBuilderPrepare_FloppyFiles(t *testing.T) {
|
|||
floppiesPath := "../../../common/test-fixtures/floppies"
|
||||
config["floppy_files"] = []string{fmt.Sprintf("%s/bar.bat", floppiesPath), fmt.Sprintf("%s/foo.ps1", floppiesPath)}
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
|
|||
config := testConfig()
|
||||
config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"}
|
||||
b = Builder{}
|
||||
_, errs := b.Prepare(config)
|
||||
_, _, errs := b.Prepare(config)
|
||||
if errs == nil {
|
||||
t.Fatalf("Nonexistent floppies should trigger multierror")
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
|||
|
||||
// Add a random key
|
||||
config["i_should_not_be_valid"] = true
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ func TestBuilderPrepare_ISOChecksum(t *testing.T) {
|
|||
|
||||
// Test bad
|
||||
config["iso_checksum"] = ""
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ func TestBuilderPrepare_ISOChecksum(t *testing.T) {
|
|||
// Test good
|
||||
config["iso_checksum"] = "FOo"
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ func TestBuilderPrepare_ISOChecksumType(t *testing.T) {
|
|||
|
||||
// Test bad
|
||||
config["iso_checksum_type"] = ""
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ func TestBuilderPrepare_ISOChecksumType(t *testing.T) {
|
|||
// Test good
|
||||
config["iso_checksum_type"] = "mD5"
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ func TestBuilderPrepare_ISOChecksumType(t *testing.T) {
|
|||
// Test unknown
|
||||
config["iso_checksum_type"] = "fake"
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ func TestBuilderPrepare_ISOChecksumType(t *testing.T) {
|
|||
// Test none
|
||||
config["iso_checksum_type"] = "none"
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) == 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -353,7 +353,7 @@ func TestBuilderPrepare_ISOUrl(t *testing.T) {
|
|||
// Test both empty
|
||||
config["iso_url"] = ""
|
||||
b = Builder{}
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -364,7 +364,7 @@ func TestBuilderPrepare_ISOUrl(t *testing.T) {
|
|||
// Test iso_url set
|
||||
config["iso_url"] = "http://www.packer.io"
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ func TestBuilderPrepare_ISOUrl(t *testing.T) {
|
|||
config["iso_url"] = "http://www.packer.io"
|
||||
config["iso_urls"] = []string{"http://www.packer.io"}
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ func TestBuilderPrepare_ISOUrl(t *testing.T) {
|
|||
}
|
||||
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -431,7 +431,7 @@ func TestBuilderPrepare_SizeNotRequiredWhenUsingExistingHarddrive(t *testing.T)
|
|||
}
|
||||
|
||||
b = Builder{}
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -455,7 +455,7 @@ func TestBuilderPrepare_SizeNotRequiredWhenUsingExistingHarddrive(t *testing.T)
|
|||
}
|
||||
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -489,7 +489,7 @@ func TestBuilderPrepare_SizeIsRequiredWhenNotUsingExistingHarddrive(t *testing.T
|
|||
}
|
||||
|
||||
b = Builder{}
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -517,7 +517,7 @@ func TestBuilderPrepare_MaximumOfSixtyFourAdditionalDisks(t *testing.T) {
|
|||
config["disk_additional_size"] = disks
|
||||
|
||||
b = Builder{}
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -537,7 +537,7 @@ func TestBuilderPrepare_CommConfig(t *testing.T) {
|
|||
config["winrm_host"] = "1.2.3.4"
|
||||
|
||||
var b Builder
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -565,7 +565,7 @@ func TestBuilderPrepare_CommConfig(t *testing.T) {
|
|||
config["ssh_host"] = "1.2.3.4"
|
||||
|
||||
var b Builder
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -593,7 +593,7 @@ func TestUserVariablesInBootCommand(t *testing.T) {
|
|||
config[packer.UserVariablesConfigKey] = map[string]string{"test-variable": "test"}
|
||||
config["boot_command"] = []string{"blah {{user `test-variable`}} blah"}
|
||||
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -634,7 +634,7 @@ func TestBuilderPrepare_UseLegacyNetworkAdapter(t *testing.T) {
|
|||
config["use_legacy_network_adapter"] = true
|
||||
|
||||
b = Builder{}
|
||||
warns, err := b.Prepare(config)
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
@ -646,7 +646,7 @@ func TestBuilderPrepare_UseLegacyNetworkAdapter(t *testing.T) {
|
|||
config["generation"] = 2
|
||||
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
hypervcommon "github.com/hashicorp/packer/builder/hyperv/common"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/common/bootcommand"
|
||||
|
@ -77,8 +78,9 @@ type Config struct {
|
|||
ctx interpolate.Context
|
||||
}
|
||||
|
||||
// Prepare processes the build configuration parameters.
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
err := config.Decode(&b.config, &config.DecodeOpts{
|
||||
Interpolate: true,
|
||||
InterpolateContext: &b.config.ctx,
|
||||
|
@ -89,7 +91,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Accumulate any errors and warnings
|
||||
|
@ -204,10 +206,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return warnings, errs
|
||||
return nil, warnings, errs
|
||||
}
|
||||
|
||||
return warnings, nil
|
||||
return nil, warnings, nil
|
||||
}
|
||||
|
||||
// Run executes a Packer build and returns a packer.Artifact representing
|
||||
|
@ -221,7 +223,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
|
||||
// Set up the state.
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("config", &b.config)
|
||||
state.Put("debug", b.config.PackerDebug)
|
||||
state.Put("driver", driver)
|
||||
state.Put("hook", hook)
|
||||
|
@ -235,23 +236,15 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
Force: b.config.PackerForce,
|
||||
Path: b.config.OutputDir,
|
||||
},
|
||||
}
|
||||
|
||||
if b.config.RawSingleISOUrl != "" || len(b.config.ISOUrls) > 0 {
|
||||
steps = append(steps,
|
||||
&common.StepDownload{
|
||||
Checksum: b.config.ISOChecksum,
|
||||
ChecksumType: b.config.ISOChecksumType,
|
||||
Description: "ISO",
|
||||
ResultKey: "iso_path",
|
||||
Url: b.config.ISOUrls,
|
||||
Extension: b.config.TargetExtension,
|
||||
TargetPath: b.config.TargetPath,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
steps = append(steps,
|
||||
&common.StepDownload{
|
||||
Checksum: b.config.ISOChecksum,
|
||||
ChecksumType: b.config.ISOChecksumType,
|
||||
Description: "ISO",
|
||||
ResultKey: "iso_path",
|
||||
Url: b.config.ISOUrls,
|
||||
Extension: b.config.TargetExtension,
|
||||
TargetPath: b.config.TargetPath,
|
||||
},
|
||||
&common.StepCreateFloppy{
|
||||
Files: b.config.FloppyFiles,
|
||||
Directories: b.config.FloppyConfig.FloppyDirectories,
|
||||
|
@ -366,9 +359,9 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
OutputDir: b.config.OutputDir,
|
||||
SkipExport: b.config.SkipExport,
|
||||
},
|
||||
}
|
||||
|
||||
// the clean up actions for each step will be executed reverse order
|
||||
)
|
||||
// the clean up actions for each step will be executed reverse order
|
||||
|
||||
// Run the steps.
|
||||
b.runner = common.NewRunner(steps, b.config.PackerConfig, ui)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue