Compare commits

..

53 Commits

Author SHA1 Message Date
Megan Marsh 324581ac9c Cut version 1.5.1 2019-12-20 11:14:09 -08:00
Megan Marsh 61023f31fd update to v1.5.1 2019-12-20 10:07:24 -08:00
Megan Marsh 57e38908f0 sort changelog 2019-12-20 09:46:20 -08:00
Megan Marsh 348e00422e Merge pull request #8509 from hashicorp/fix_step_import_panic
Remove config dependency from inside StepImport
2019-12-20 09:19:30 -08:00
Megan Marsh a276fa147a update changelog 2019-12-20 06:56:48 -08:00
Moss 7912e496aa Remove config dependency inside StepImport 2019-12-20 11:58:28 +01:00
Adrien Delorme 1b532fc816 link to guides in HCL docs (#8526) 2019-12-20 11:23:48 +01:00
dependabot[bot] da8e215536 Bump rack from 1.6.11 to 1.6.12 in /website (#8524)
Bumps [rack](https://github.com/rack/rack) from 1.6.11 to 1.6.12.
- [Release notes](https://github.com/rack/rack/releases)
- [Changelog](https://github.com/rack/rack/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rack/rack/compare/1.6.11...1.6.12)

Signed-off-by: dependabot[bot] <support@github.com>
2019-12-20 10:50:47 +01:00
Megan Marsh 4059ed75f5 update docs to mention ssh auth sock env var (#8523)
Closes #8358

Add some docs to alleviate confusion.
2019-12-20 08:27:14 +01:00
Megan Marsh 127905e855 remove time flaky time limited tests (#8522)
* remove flaky test. It isn't very useful anyway given that we're slowly adding retries to the checks for lockfiles

* remove time-component from retry test; in underpowered CI builds, this can flake fairly often.
2019-12-20 08:16:18 +01:00
zhuzhih2017 66445ecd2d Merge pull request #8425 from haoshuwei/master
add show expired arg when describe image
2019-12-20 13:33:55 +08:00
haoshuwei 37dc411f30 add skip_image_validation arg to use an expired image as the soure image
Signed-off-by: haoshuwei <haoshuwei24@gmail.com>
2019-12-20 11:28:31 +08:00
Megan Marsh 7ce9992357 move osx code signing to before checksums are calculated 2019-12-19 14:07:10 -08:00
Wilken Rivera f45d315be4 Merge pull request #8518 from hashicorp/update_jdcloud_config_pointer
update jdcloud statebag to use pointers for config, to bring in line …
2019-12-19 15:45:40 -05:00
Wilken Rivera 0ded72670f Merge pull request #8519 from hashicorp/vagrant_cloud_pp_config
Vagrant cloud pp config
2019-12-19 15:36:02 -05:00
Megan Marsh f47d9f1b1f Merge pull request #8514 from hashicorp/fix_5821
Configure NAT interface before forwarded port mapping
2019-12-19 11:30:33 -08:00
Megan Marsh b23425f637 use pointer to config rather than config 2019-12-19 11:27:21 -08:00
Megan Marsh 09489da149 update jdcloud statebag to use pointers for config, to bring in line with other implementations 2019-12-19 11:17:04 -08:00
Megan Marsh 5054b1becc Merge pull request #8513 from hashicorp/fix_config_pointer_panic
fix config pointers panic
2019-12-19 11:07:15 -08:00
Megan Marsh bbc5bc0658 Merge pull request #8501 from hashicorp/hcl_docs
Better docs for HCL
2019-12-19 09:55:52 -08:00
Megan Marsh e212c27175 update changelog 2019-12-19 09:32:53 -08:00
Adrien Delorme f1e6f8eac1 removed unused config puts 2019-12-19 18:06:39 +01:00
Adrien Delorme a67948f155 fix config pointers 2019-12-19 17:51:57 +01:00
Adrien Delorme d0e9242b3d trigger preview 2019-12-19 17:31:07 +01:00
Moss 9216f43463 Configure NAT interface before forwarded port mapping 2019-12-19 17:03:31 +01:00
Wilken Rivera 412df59ea5 Merge pull request #8506 from PumpkinSeed/I8487-huaweicloud-ecs-builder
Add Huawei Cloud ECS builder to docs
2019-12-19 10:34:51 -05:00
Ferenc Fabian 04b269461c Update website/source/partials/builders/_community_builders.html.md
Co-Authored-By: Adrien Delorme <azr@users.noreply.github.com>
2019-12-19 16:24:48 +01:00
Adrien Delorme 46ce0529dd docs ++ 2019-12-19 16:23:30 +01:00
Adrien Delorme fbd3796377 Update index.html.md.erb 2019-12-19 15:40:08 +01:00
Adrien Delorme 31cad234f2 Update index.html.md.erb 2019-12-19 15:34:26 +01:00
Adrien Delorme 1d066082a5 Update index.html.md.erb 2019-12-19 15:28:29 +01:00
Adrien Delorme 4c3fa0ef26 document split files & main building blocks in guide 2019-12-19 14:58:44 +01:00
Moss 42cf9ef064 Remove pointer fixing panic on interface conversion 2019-12-19 13:30:54 +01:00
Megan Marsh 9eda2031d2 Remove redundant placeholder (#8503) 2019-12-19 10:39:46 +01:00
PumpkinSeed 6a185b7c64 Add Huawei Cloud ECS 2019-12-19 10:16:51 +01:00
Megan Marsh a6c56aa4e2 fix build func docs 2019-12-18 16:53:17 -08:00
Megan Marsh f6878d6a2a update master to 1.5.1-dev 2019-12-18 16:40:17 -08:00
Adrien Delorme 7fe51022ca add expression 2019-12-18 18:16:10 +01:00
Adrien Delorme 0436457fd7 fix sidebar current 2019-12-18 17:14:02 +01:00
Adrien Delorme 8cdf8ca442 add syntax-json for HCL 2019-12-18 17:10:59 +01:00
Adrien Delorme bb72a0c0ce document hcl language & syntax 2019-12-18 16:57:36 +01:00
Adrien Delorme 26ceea0c36 update custon provider docs 2019-12-18 16:13:52 +01:00
Adrien Delorme 04a8758811 Update website/source/guides/hcl/from-json-v1/index.html.md.erb
Co-Authored-By: Wilken Rivera <dev@wilkenrivera.com>
2019-12-18 15:59:53 +01:00
Adrien Delorme 978af9188f Update website/source/guides/hcl/component-object-spec/index.html.md.erb
Co-Authored-By: Wilken Rivera <dev@wilkenrivera.com>
2019-12-18 15:59:33 +01:00
Adrien Delorme da12c73726 Update website/source/guides/hcl/component-object-spec/index.html.md.erb
Co-Authored-By: Wilken Rivera <dev@wilkenrivera.com>
2019-12-18 15:59:26 +01:00
Adrien Delorme 971eac1701 Update website/source/guides/hcl/component-object-spec/index.html.md.erb
Co-Authored-By: Wilken Rivera <dev@wilkenrivera.com>
2019-12-18 15:59:16 +01:00
Adrien Delorme 9219a606a3 move "Installing Packer" a little lower in the nav bar 2019-12-18 15:57:28 +01:00
Adrien Delorme f3629dbaf7 Update index.html.md.erb
fix sidebar_current
2019-12-18 15:57:01 +01:00
Adrien Delorme 8dc587967e Update guides.erb 2019-12-18 15:51:38 +01:00
Adrien Delorme 93b9f3cb80 rename 2019-12-18 15:51:32 +01:00
Adrien Delorme da90c22c35 Update index.html.md.erb
better title
2019-12-18 15:51:13 +01:00
Adrien Delorme 1ada06b2d7 fix sidebar_current of guide/hcl/from-json-v1 2019-12-18 15:22:48 +01:00
Adrien Delorme 8c21916606 add guide on how to make ones component HCL2 enabled 2019-12-18 15:01:48 +01:00
60 changed files with 924 additions and 133 deletions
+32
View File
@@ -1,3 +1,32 @@
## 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:
@@ -11,6 +40,8 @@
[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]
@@ -23,6 +54,7 @@
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]
+3
View File
@@ -26,6 +26,9 @@ type AlicloudAccessConfig struct {
// 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"`
// 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"`
+2
View File
@@ -57,6 +57,7 @@ type FlatConfig struct {
AlicloudSecretKey *string `mapstructure:"secret_key" required:"true" cty:"secret_key"`
AlicloudRegion *string `mapstructure:"region" required:"true" 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"`
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"`
@@ -160,6 +161,7 @@ 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},
"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},
-3
View File
@@ -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")
+1 -1
View File
@@ -53,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)
-1
View File
@@ -183,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)
-1
View File
@@ -223,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)
+1 -1
View File
@@ -46,7 +46,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
state := new(multistep.BasicStateBag)
state.Put("hook", hook)
state.Put("ui", ui)
state.Put("config", b.config)
state.Put("config", &b.config)
steps := []multistep.Step{
+1 -1
View File
@@ -142,7 +142,7 @@ func (s *stepCreateJDCloudInstance) Cleanup(state multistep.StateBag) {
func createElasticIp(state multistep.StateBag) (string, error) {
generalConfig := state.Get("config").(Config)
generalConfig := state.Get("config").(*Config)
regionId := generalConfig.RegionId
credential := core.NewCredentials(generalConfig.AccessKey, generalConfig.SecretKey)
vpcclient := vpcClient.NewVpcClient(credential)
+1 -1
View File
@@ -47,7 +47,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (ret
}
state := new(multistep.BasicStateBag)
state.Put("config", b.config)
state.Put("config", &b.config)
state.Put("hook", hook)
state.Put("ui", ui)
+1 -1
View File
@@ -53,7 +53,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
// Setup the state bag
state := new(multistep.BasicStateBag)
state.Put("config", b.config)
state.Put("config", &b.config)
state.Put("hook", hook)
state.Put("ui", ui)
state.Put("wrappedCommand", CommandWrapper(wrappedCommand))
+1 -1
View File
@@ -47,7 +47,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
// Setup the state bag
state := new(multistep.BasicStateBag)
state.Put("config", b.config)
state.Put("config", &b.config)
state.Put("hook", hook)
state.Put("ui", ui)
state.Put("wrappedCommand", CommandWrapper(wrappedCommand))
-1
View File
@@ -45,7 +45,6 @@ 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("hook", hook)
state.Put("ui", ui)
+1 -1
View File
@@ -34,7 +34,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
state := new(multistep.BasicStateBag)
state.Put("config", b.config)
state.Put("config", &b.config)
state.Put("hook", hook)
state.Put("ui", ui)
+1 -1
View File
@@ -67,7 +67,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
runID := fmt.Sprintf("%s_%s", b.config.ImageName, os.Getenv("PACKER_RUN_UUID"))
// Populate the state bag
state := new(multistep.BasicStateBag)
state.Put("config", b.config)
state.Put("config", &b.config)
state.Put("hook", hook)
state.Put("ui", ui)
state.Put("client", client)
+1 -1
View File
@@ -46,7 +46,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
// Populate the state bag
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)
-1
View File
@@ -104,7 +104,6 @@ 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("oapi", oapiconn)
state.Put("hook", hook)
state.Put("ui", ui)
+1 -1
View File
@@ -42,7 +42,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("debug", b.config.PackerDebug)
state.Put("driver", driver)
state.Put("hook", hook)
+1 -1
View File
@@ -32,7 +32,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
state := new(multistep.BasicStateBag)
state.Put("config", b.config)
state.Put("config", &b.config)
state.Put("hook", hook)
state.Put("ui", ui)
steps := []multistep.Step{
+1 -1
View File
@@ -44,7 +44,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
}
state := new(multistep.BasicStateBag)
state.Put("config", b.config)
state.Put("config", &b.config)
state.Put("client", client)
state.Put("hook", hook)
state.Put("ui", ui)
+1 -1
View File
@@ -237,7 +237,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("debug", b.config.PackerDebug)
state.Put("driver", driver)
state.Put("hook", hook)
+1 -1
View File
@@ -185,7 +185,7 @@ func (d *VBox42Driver) VBoxManage(args ...string) error {
ShouldRetry: func(err error) bool {
return strings.Contains(err.Error(), "VBOX_E_INVALID_OBJECT_STATE")
},
RetryDelay: func() time.Duration { return 2 * time.Minute },
RetryDelay: func() time.Duration { return 1 * time.Minute },
}.Run(ctx, func(ctx context.Context) error {
_, err := d.VBoxManageWithOutput(args...)
return err
+14 -1
View File
@@ -63,9 +63,22 @@ func (s *StepForwardSSH) Run(ctx context.Context, state multistep.StateBag) mult
s.l.Listener.Close() // free port, but don't unlock lock file
sshHostPort = s.l.Port
// Make sure to configure the network interface to NAT
command := []string{
"modifyvm", vmName,
"--nic1",
"nat",
}
if err := driver.VBoxManage(command...); err != nil {
err := fmt.Errorf("Failed to configure NAT interface: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Create a forwarded port mapping to the VM
ui.Say(fmt.Sprintf("Creating forwarded port mapping for communicator (SSH, WinRM, etc) (host port %d)", sshHostPort))
command := []string{
command = []string{
"modifyvm", vmName,
"--natpf1",
fmt.Sprintf("packercomm,tcp,127.0.0.1,%d,,%d", sshHostPort, guestPort),
@@ -109,70 +109,6 @@ func TestStepShutdown_shutdownTimeout(t *testing.T) {
}
}
func TestStepShutdown_shutdownDelay(t *testing.T) {
state := testState(t)
step := new(StepShutdown)
step.Command = "poweroff"
step.Timeout = 5 * time.Second
step.Delay = 2 * time.Second
step.DisableShutdown = false
comm := new(packer.MockCommunicator)
state.Put("communicator", comm)
state.Put("vmName", "foo")
driver := state.Get("driver").(*DriverMock)
driver.IsRunningReturn = true
start := time.Now()
go func() {
time.Sleep(10 * time.Millisecond)
driver.Lock()
defer driver.Unlock()
driver.IsRunningReturn = false
}()
// Test the run
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
testDuration := time.Since(start)
if testDuration < 2500*time.Millisecond || testDuration > 2700*time.Millisecond {
t.Fatalf("incorrect duration %s", testDuration)
}
if _, ok := state.GetOk("error"); ok {
t.Fatal("should NOT have error")
}
step.Delay = 0
driver.IsRunningReturn = true
start = time.Now()
go func() {
time.Sleep(10 * time.Millisecond)
driver.Lock()
defer driver.Unlock()
driver.IsRunningReturn = false
}()
// Test the run
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
testDuration = time.Since(start)
if testDuration > 700*time.Millisecond {
t.Fatalf("incorrect duration %s", testDuration)
}
if _, ok := state.GetOk("error"); ok {
t.Fatal("should NOT have error")
}
}
func TestStepShutdown_DisableShutdown(t *testing.T) {
state := testState(t)
step := new(StepShutdown)
+4 -3
View File
@@ -42,7 +42,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("debug", b.config.PackerDebug)
state.Put("driver", driver)
state.Put("hook", hook)
@@ -86,8 +86,9 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Url: []string{b.config.SourcePath},
},
&StepImport{
Name: b.config.VMName,
ImportFlags: b.config.ImportFlags,
Name: b.config.VMName,
ImportFlags: b.config.ImportFlags,
KeepRegistered: b.config.KeepRegistered,
},
&vboxcommon.StepAttachGuestAdditions{
GuestAdditionsMode: b.config.GuestAdditionsMode,
+4 -4
View File
@@ -11,8 +11,9 @@ import (
// This step imports an OVF VM into VirtualBox.
type StepImport struct {
Name string
ImportFlags []string
Name string
ImportFlags []string
KeepRegistered bool
vmName string
}
@@ -42,11 +43,10 @@ func (s *StepImport) Cleanup(state multistep.StateBag) {
driver := state.Get("driver").(vboxcommon.Driver)
ui := state.Get("ui").(packer.Ui)
config := state.Get("config").(*Config)
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
if (config.KeepRegistered) && (!cancelled && !halted) {
if (s.KeepRegistered) && (!cancelled && !halted) {
ui.Say("Keeping virtual machine registered with VirtualBox host (keep_registered = true)")
return
}
+13 -8
View File
@@ -14,11 +14,8 @@ func TestStepImport_impl(t *testing.T) {
func TestStepImport(t *testing.T) {
state := testState(t)
cfg := testConfig(t)
var c Config
c.Prepare(cfg)
state.Put("vm_path", "foo")
state.Put("config", &c)
step := new(StepImport)
step.Name = "bar"
@@ -46,16 +43,24 @@ func TestStepImport(t *testing.T) {
} else if name != "bar" {
t.Fatalf("bad: %#v", name)
}
}
// Test cleanup
c.KeepRegistered = true
func TestStepImport_Cleanup(t *testing.T) {
state := testState(t)
state.Put("vm_path", "foo")
step := new(StepImport)
step.vmName = "bar"
driver := state.Get("driver").(*vboxcommon.DriverMock)
step.KeepRegistered = true
step.Cleanup(state)
if driver.DeleteCalled {
t.Fatal("delete should not be called")
}
c.KeepRegistered = false
state.Put(multistep.StateHalted, true)
step.Cleanup(state)
if !driver.DeleteCalled {
t.Fatal("delete should be called")
-1
View File
@@ -42,7 +42,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)
-1
View File
@@ -61,7 +61,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("dir", dir)
state.Put("driver", driver)
+2 -1
View File
@@ -113,7 +113,8 @@ type SSH struct {
// use this option with a key pair already configured in the source AMI,
// leave the `ssh_keypair_name` blank. To associate an existing key pair in
// AWS with the source instance, set the `ssh_keypair_name` field to the
// name of the key pair.
// name of the key pair. The environment variable `SSH_AUTH_SOCK` must be
// set for this option to work properly.
SSHAgentAuth bool `mapstructure:"ssh_agent_auth"`
// If true, SSH agent forwarding will be disabled. Defaults to `false`.
SSHDisableAgentForwarding bool `mapstructure:"ssh_disable_agent_forwarding"`
@@ -21,6 +21,7 @@ type FlatConfig struct {
AlicloudSecretKey *string `mapstructure:"secret_key" required:"true" cty:"secret_key"`
AlicloudRegion *string `mapstructure:"region" required:"true" 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"`
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"`
@@ -132,6 +133,7 @@ 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},
"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},
@@ -166,7 +166,7 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
// Set up the state
state := new(multistep.BasicStateBag)
state.Put("config", p.config)
state.Put("config", &p.config)
state.Put("client", p.client)
state.Put("artifact", artifact)
state.Put("artifactFilePath", artifact.Files()[0])
@@ -19,7 +19,7 @@ type stepCreateVersion struct {
func (s *stepCreateVersion) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*VagrantCloudClient)
ui := state.Get("ui").(packer.Ui)
config := state.Get("config").(Config)
config := state.Get("config").(*Config)
box := state.Get("box").(*Box)
ui.Say(fmt.Sprintf("Creating version: %s", config.Version))
@@ -17,7 +17,7 @@ func (s *stepReleaseVersion) Run(ctx context.Context, state multistep.StateBag)
ui := state.Get("ui").(packer.Ui)
box := state.Get("box").(*Box)
version := state.Get("version").(*Version)
config := state.Get("config").(Config)
config := state.Get("config").(*Config)
ui.Say(fmt.Sprintf("Releasing version: %s", version.Version))
@@ -28,7 +28,7 @@ type stepVerifyBox struct {
func (s *stepVerifyBox) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*VagrantCloudClient)
ui := state.Get("ui").(packer.Ui)
config := state.Get("config").(Config)
config := state.Get("config").(*Config)
ui.Say(fmt.Sprintf("Verifying box is accessible: %s", config.Tag))
-2
View File
@@ -125,8 +125,6 @@ type KnifeTemplate struct {
func (p *Provisioner) ConfigSpec() hcldec.ObjectSpec { return p.config.FlatMapstructure().HCL2Spec() }
func (p *Provisioner) Prepare(raws ...interface{}) error {
// Create passthrough for build-generated data
p.config.ctx.Data = packer.BasicPlaceholderData()
err := config.Decode(&p.config, &config.DecodeOpts{
Interpolate: true,
InterpolateContext: &p.config.ctx,
-3
View File
@@ -91,9 +91,6 @@ func (p *Provisioner) defaultExecuteCommand() string {
func (p *Provisioner) ConfigSpec() hcldec.ObjectSpec { return p.config.FlatMapstructure().HCL2Spec() }
func (p *Provisioner) Prepare(raws ...interface{}) error {
// Create passthrough for build-generated data
p.config.ctx.Data = packer.BasicPlaceholderData()
err := config.Decode(&p.config, &config.DecodeOpts{
Interpolate: true,
InterpolateContext: &p.config.ctx,
@@ -154,8 +154,6 @@ type EnvVarsTemplate struct {
func (p *Provisioner) ConfigSpec() hcldec.ObjectSpec { return p.config.FlatMapstructure().HCL2Spec() }
func (p *Provisioner) Prepare(raws ...interface{}) error {
// Create passthrough for build-generated data
p.config.ctx.Data = packer.BasicPlaceholderData()
err := config.Decode(&p.config, &config.DecodeOpts{
Interpolate: true,
InterpolateContext: &p.config.ctx,
-3
View File
@@ -148,9 +148,6 @@ type EnvVarsTemplate struct {
func (p *Provisioner) ConfigSpec() hcldec.ObjectSpec { return p.config.FlatMapstructure().HCL2Spec() }
func (p *Provisioner) Prepare(raws ...interface{}) error {
// Create passthrough for build-generated data
p.config.ctx.Data = packer.BasicPlaceholderData()
err := config.Decode(&p.config, &config.DecodeOpts{
Interpolate: true,
InterpolateContext: &p.config.ctx,
+2 -1
View File
@@ -39,6 +39,8 @@ for PLATFORM in $(find ./pkg -mindepth 1 -maxdepth 1 -type d); do
popd >/dev/null 2>&1
done
./scripts/sign.sh
if [ -z $NOSIGN ]; then
echo "==> Signing..."
pushd ./pkg/dist
@@ -48,7 +50,6 @@ if [ -z $NOSIGN ]; then
popd
fi
./scripts/sign.sh
hc-releases upload $DIR/pkg/dist/
hc-releases publish
+1 -1
View File
@@ -9,7 +9,7 @@ import (
var GitCommit string
// The main version number that is being run at the moment.
const Version = "1.5.0"
const Version = "1.5.1"
// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
+1 -1
View File
@@ -112,7 +112,7 @@ GEM
tilt (>= 1.4.1, < 3)
padrino-support (0.12.9)
activesupport (>= 3.1)
rack (1.6.11)
rack (1.6.12)
rack-livereload (0.3.17)
rack
rack-test (1.1.0)
+1 -1
View File
@@ -2,7 +2,7 @@ set :base_url, "https://www.packer.io/"
activate :hashicorp do |h|
h.name = "packer"
h.version = "1.5.0"
h.version = "1.5.1"
h.github_slug = "hashicorp/packer"
h.website_root = "website"
end
@@ -0,0 +1,222 @@
---
layout: "docs"
page_title: "Expressions - Configuration Language"
sidebar_current: configuration-expressions
description: |-
HCL allows the use of expressions to access data exported
by resources and to transform and combine that data to produce other values.
---
# Expressions
_Expressions_ are used to refer to or compute values within a configuration.
The simplest expressions are just literal values, like `"hello"` or `5`, but
HCL also allows more complex expressions such as references to data exported by
resources, arithmetic, conditional evaluation, and a number of built-in
functions.
Expressions can be used in a number of places in HCL, but some contexts limit
which expression constructs are allowed, such as requiring a literal value of a
particular type or forbidding. Each language feature's documentation describes
any restrictions it places on expressions.
The rest of this page describes all of the features of Packer's
expression syntax.
## Types and Values
The result of an expression is a _value_. All values have a _type_, which
dictates where that value can be used and what transformations can be
applied to it.
HCL uses the following types for its values:
* `string`: a sequence of Unicode characters representing some text, like
`"hello"`.
* `number`: a numeric value. The `number` type can represent both whole
numbers like `15` and fractional values like `6.283185`.
* `bool`: either `true` or `false`. `bool` values can be used in conditional
logic.
* `list` (or `tuple`): a sequence of values, like
`["us-west-1a", "us-west-1c"]`. Elements in a list or tuple are identified by
consecutive whole numbers, starting with zero.
* `map` (or `object`): a group of values identified by named labels, like
`{name = "Mabel", age = 52}`.
Strings, numbers, and bools are sometimes called _primitive types._
Lists/tuples and maps/objects are sometimes called _complex types,_ _structural
types,_ or _collection types._
Finally, there is one special value that has _no_ type:
* `null`: a value that represents _absence_ or _omission._ If you set an
argument of a source or module to `null`, Packer behaves as though you
had completely omitted it — it will use the argument's default value if it has
one, or raise an error if the argument is mandatory. `null` is most useful in
conditional expressions, so you can dynamically omit an argument if a
condition isn't met.
### Advanced Type Details
In most situations, lists and tuples behave identically, as do maps and objects.
Whenever the distinction isn't relevant, the Packer documentation uses each
pair of terms interchangeably (with a historical preference for "list" and
"map").
However, module authors and provider developers should understand the
differences between these similar types (and the related `set` type), since they
offer different ways to restrict the allowed values for input variables and
source arguments.
### Type Conversion
Expressions are most often used to set values for the arguments of resources and
child modules. In these cases, the argument has an expected type and the given
expression must produce a value of that type.
Where possible, Packer automatically converts values from one type to
another in order to produce the expected type. If this isn't possible, Packer
will produce a type mismatch error and you must update the configuration with a
more suitable expression.
Packer automatically converts number and bool values to strings when needed.
It also converts strings to numbers or bools, as long as the string contains a
valid representation of a number or bool value.
* `true` converts to `"true"`, and vice-versa
* `false` converts to `"false"`, and vice-versa
* `15` converts to `"15"`, and vice-versa
## Literal Expressions
A _literal expression_ is an expression that directly represents a particular
constant value. Packer has a literal expression syntax for each of the value
types described above:
* Strings are usually represented by a double-quoted sequence of Unicode
characters, `"like this"`. There is also a "heredoc" syntax for more complex
strings. String literals are the most complex kind of literal expression in
Packer, and have additional documentation on this page:
* See [String Literals](#string-literals) below for information about escape
sequences and the heredoc syntax.
* See [String Templates](#string-templates) below for information about
interpolation and template directives.
* Numbers are represented by unquoted sequences of digits with or without a
decimal point, like `15` or `6.283185`.
* Bools are represented by the unquoted symbols `true` and `false`.
* The null value is represented by the unquoted symbol `null`.
* Lists/tuples are represented by a pair of square brackets containing a
comma-separated sequence of values, like `["a", 15, true]`.
List literals can be split into multiple lines for readability, but always
require a comma between values. A comma after the final value is allowed,
but not required. Values in a list can be arbitrary expressions.
* Maps/objects are represented by a pair of curly braces containing a series of
`<KEY> = <VALUE>` pairs:
```hcl
{
name = "John"
age = 52
}
```
Key/value pairs can be separated by either a comma or a line break. Values
can be arbitrary expressions. Keys are strings; they can be left unquoted if
they are a valid [identifier](./syntax.html#identifiers), but must be quoted
otherwise. You can use a non-literal expression as a key by wrapping it in
parentheses, like `(var.business_unit_tag_name) = "SRE"`.
## References to Named Values
Packer makes one named values available.
The following named values are available:
* `source.<SOURCE TYPE>.<NAME>` is an object representing a
[source](./sources.html) of the given type
and name.
## String Literals
HCL has two different syntaxes for string literals. The
most common is to delimit the string with quote characters (`"`), like
`"hello"`. In quoted strings, the backslash character serves as an escape
sequence, with the following characters selecting the escape behavior:
| Sequence | Replacement |
| ------------ | ----------------------------------------------------------------------------- |
| `\n` | Newline |
| `\r` | Carriage Return |
| `\t` | Tab |
| `\"` | Literal quote (without terminating the string) |
| `\\` | Literal backslash |
| `\uNNNN` | Unicode character from the basic multilingual plane (NNNN is four hex digits) |
| `\UNNNNNNNN` | Unicode character from supplementary planes (NNNNNNNN is eight hex digits) |
The alternative syntax for string literals is the so-called Here Documents or
"heredoc" style, inspired by Unix shell languages. This style allows multi-line
strings to be expressed more clearly by using a custom delimiter word on a line
of its own to close the string:
```hcl
<<EOF
hello
world
EOF
```
The `<<` marker followed by any identifier at the end of a line introduces the
sequence. Packer then processes the following lines until it finds one that
consists entirely of the identifier given in the introducer. In the above
example, `EOF` is the identifier selected. Any identifier is allowed, but
conventionally this identifier is in all-uppercase and begins with `EO`, meaning
"end of". `EOF` in this case stands for "end of text".
The "heredoc" form shown above requires that the lines following be flush with
the left margin, which can be awkward when an expression is inside an indented
block:
```hcl
block {
value = <<EOF
hello
world
EOF
}
```
To improve on this, Packer also accepts an _indented_ heredoc string variant
that is introduced by the `<<-` sequence:
```hcl
block {
value = <<-EOF
hello
world
EOF
}
```
In this case, Packer analyses the lines in the sequence to find the one
with the smallest number of leading spaces, and then trims that many spaces
from the beginning of all of the lines, leading to the following result:
```
hello
world
```
Backslash sequences are not interpreted in a heredoc string expression.
Instead, the backslash character is interpreted literally.
In both quoted and heredoc string expressions, Packer supports template
sequences that begin with `${` and `%{`. These are described in more detail
in the following section. To include these sequences _literally_ without
beginning a template sequence, double the leading character: `$${` or `%%{`.
## String Templates
Within quoted and heredoc string expressions, the sequences `${` and `%{` begin
_template sequences_. Templates let you directly embed expressions into a string
literal, to dynamically construct strings from other values.
@@ -0,0 +1,77 @@
---
layout: "docs"
page_title: "Configuration Language"
sidebar_current: "configuration"
description: |-
Packer uses text files to describe infrastructure and to set variables.
These text files are called Packer _configurations_ and are
written in the HCL language.
---
# HCL Configuration Language
Packer uses the Hashicorp Configuration Language - HCL - designed to allow
concise descriptions of the required steps to get to a build file. This page
describes the features of HCL2 exhaustively, if you would like to give a quick
try to HCL2, you can also read the quicker [HCL2 getting started
guide](/guides/hcl).
## Builds
The main purpose of the HCL language is defining builds and sources. All other
language features exist only to make the definition of builds more flexible and
convenient.
`packer build` takes one argument. When a directory is passed, all files in the
folder with a name ending with ".pkr.hcl" or ".pkr.json" will be parsed using
the HCL2 format. When a file ending with ".pkr.hcl" or ".pkr.json" is passed it
will be parsed using the HCL2 schema. For every other case; the *JSON only* old
packer schema will be used.
## Arguments, Blocks, and Expressions
The syntax of the HCL language consists of only a few basic elements:
```hcl
source "amazon-ebs" "main" {
ami_name = "main-ami"
}
<BLOCK TYPE> "<BLOCK LABEL>" "<BLOCK LABEL>" {
# Block body
<IDENTIFIER> = <EXPRESSION> # Argument
}
```
- _Blocks_ are containers for other content and usually represent the
configuration of some kind of object, like a source. Blocks have a
_block type,_ can have zero or more _labels,_ and have a _body_ that contains
any number of arguments and nested blocks. Most of Packer's features are
controlled by top-level blocks in a configuration file.
- _Arguments_ assign a value to a name. They appear within blocks.
- _Expressions_ represent a value, either literally or by referencing and
combining other values. They appear as values for arguments, or within other
expressions.
For full details about Packer's syntax, see:
- [Configuration Syntax](./syntax.html)
- [Expressions](./expressions.html)
## Code Organization
The HCL language uses configuration files that are named with the `.pkr.hcl`
file extension. There is also [a JSON-based variant of the
language](./syntax-json.html) that is named with the `.pkr.json` file
extension.
Configuration files must always use UTF-8 encoding, and by convention are
usually maintained with Unix-style line endings (LF) rather than Windows-style
line endings (CRLF), though both are accepted.
## Configuration Ordering
The ordering of root blocks is not significant. The order of `provisioner` or
`post-processor` blocks within a `build` is the only major feature where block
order matters.
@@ -0,0 +1,276 @@
---
layout: "docs"
page_title: "JSON Configuration Syntax - Configuration Language"
sidebar_current: configuration-json-syntax
description: |-
In addition to the native syntax that is most commonly used with Packer,
the HCL language can also be expressed in a JSON-compatible syntax.
---
# JSON Configuration Syntax
Most Packer configurations are written in [the native HCL
syntax](./syntax.html), which is designed to be easy for humans to read and
update.
Packer also supports an alternative syntax that is JSON-compatible. This
syntax is useful when generating portions of a configuration programmatically,
since existing JSON libraries can be used to prepare the generated
configuration files.
The JSON syntax is defined in terms of the native syntax. Everything that can
be expressed in native syntax can also be expressed in JSON syntax, but some
constructs are more complex to represent in JSON due to limitations of the
JSON grammar.
Packer expects native syntax for files named with a `.pkr.hcl` suffix, and JSON
syntax for files named with a `.pkr.json` suffix.
The low-level JSON syntax, just as with the native syntax, is defined in terms
of a specification called _HCL_. It is not necessary to know all of the details
of HCL syntax or its JSON mapping in order to use Packer, and so this page
summarizes the most important differences between native and JSON syntax. If
you are interested, you can find a full definition of HCL's JSON syntax in [its
specification](https://github.com/hashicorp/hcl/blob/hcl2/hclsyntax/spec.md).
## JSON File Structure
At the root of any JSON-based Packer configuration is a JSON object. The
properties of this object correspond to the top-level block types of the
Packer language. For example:
```json
{
"variables": {
"example": "value"
}
}
```
Each top-level object property must match the name of one of the expected
top-level block types. Block types that expect labels, such as `variable` shown
above, are represented by one nested object value for each level of label.
`source` blocks expect two labels, so two levels of nesting are required:
```json
{
"source": {
"amazon-ebs": {
"example": {
"instance_type": "t2.micro",
"ami_name": "ami-abc123"
}
}
}
}
```
After any nested objects representing the labels, finally one more nested
object represents the body of the block itself. In the above example the
`instance_type` and `ami_name` arguments for `source "amazon-ebs" "example"`
are specified.
Taken together, the above two configuration files are equivalent to the
following blocks in the native syntax:
```hcl
variables {
example = "value"
}
source "amazon-ebs" "example" {
instance_type = "t2.micro"
ami_name = "ami-abc123"
}
```
Within each top-level block type the rules for mapping to JSON are slightly
different (see [Block-type-specific Exceptions][inpage-exceptions] below), but the following general rules apply in most cases:
* The JSON object representing the block body contains properties that
correspond either to argument names or to nested block type names.
* Where a property corresponds to an argument that accepts
[arbitrary expressions](./expressions.html) in the native syntax, the
property value is mapped to an expression as described under
[_Expression Mapping_](#expression-mapping) below. For arguments that
do _not_ accept arbitrary expressions, the interpretation of the property
value depends on the argument, as described in the
[block-type-specific exceptions](#block-type-specific-exceptions)
given later in this page.
* Where a property name corresponds to an expected nested block type name,
the value is interpreted as described under
[_Nested Block Mapping_](#nested-block-mapping) below, unless otherwise
stated in [the block-type-specific exceptions](#block-type-specific-exceptions)
given later in this page.
## Expression Mapping
Since JSON grammar is not able to represent all of the Packer language
[expression syntax](./expressions.html), JSON values interpreted as expressions
are mapped as follows:
| JSON | Packer Language Interpretation |
| ------- | ------------------------------------------------------------------------------------------------------------- |
| Boolean | A literal `bool` value. |
| Number | A literal `number` value. |
| String | Parsed as a [string template](./expressions.html#string-templates) and then evaluated as described below. |
| Object | Each property value is mapped per this table, producing an `object(...)` value with suitable attribute types. |
| Array | Each element is mapped per this table, producing a `tuple(...)` value with suitable element types. |
| Null | A literal `null`. |
When a JSON string is encountered in a location where arbitrary expressions are
expected, its value is first parsed as a [string template](./expressions.html#string-templates)
and then it is evaluated to produce the final result.
If the given template consists _only_ of a single interpolation sequence,
the result of its expression is taken directly, without first converting it
to a string. This allows non-string expressions to be used within the
JSON syntax.
## Nested Block Mapping
When a JSON object property is named after a nested block type, the value
of this property represents one or more blocks of that type. The value of
the property must be either a JSON object or a JSON array.
The simplest situation is representing only a single block of the given type
when that type expects no labels, as with the `tags` nested block used
within `source` blocks:
```json
{
"source": {
"amazon-ebs": {
"example": {
"tags": {
"key": "value"
}
}
}
}
}
```
The above is equivalent to the following native syntax configuration:
```hcl
source "amazon-ebs" "example" {
tags {
key = "value"
}
}
```
When the nested block type requires one or more labels, or when multiple
blocks of the same type can be given, the mapping gets a little more
complicated. For example, the `provisioner` nested block type used
within `source` blocks expects a label giving the provisioner to use,
and the ordering of provisioner blocks is significant to decide the order
of operations.
The following native syntax example shows a `source` block with a number
of provisioners of different types:
```hcl
source "amazon-ebs" "example" {
# (source configuration omitted for brevity)
provisioner "shell-local" {
inline = ["echo 'Hello World' >example.txt"]
}
provisioner "file" {
source = "example.txt"
destination = "/tmp/example.txt"
}
provisioner "shell" {
inline = [
"sudo install-something -f /tmp/example.txt",
]
}
}
```
In order to preserve the order of these blocks, you must use a JSON array
as the direct value of the property representing this block type, as in
this JSON equivalent of the above:
```json
{
"source": {
"amazon-ebs": {
"example": {
"provisioner": [
{
"shell-local": {
"inline": ["echo 'Hello World' >example.txt"]
}
},
{
"file": {
"source": "example.txt",
"destination": "/tmp/example.txt"
}
},
{
"shell": {
"inline": ["sudo install-something -f /tmp/example.txt"]
}
}
]
}
}
}
}
```
Each element of the `provisioner` array is an object with a single property
whose name represents the label for each `provisioner` block. For block types
that expect multiple labels, this pattern of alternating array and object
nesting can be used for each additional level.
If a nested block type requires labels but the order does _not_ matter, you
may omit the array and provide just a single object whose property names
correspond to unique block labels. This is allowed as a shorthand for the above
for simple cases, but the alternating array and object approach is the most
general. We recommend using the most general form if systematically converting
from native syntax to JSON, to ensure that the meaning of the configuration is
preserved exactly.
### Comment Properties
Although we do not recommend hand-editing of JSON syntax configuration files
-- this format is primarily intended for programmatic generation and consumption --
a limited form of _comments_ are allowed inside JSON objects that represent
block bodies using a special property name:
```json
{
"source": {
"amazon-ebs": {
"example": {
"//": "This instance runs the scheduled tasks for backup",
"instance_type": "t2.micro",
"ami_name": "ami-abc123"
}
}
}
}
```
In any object that represents a block body, properties named `"//"` are
ignored by Packer entirely. This exception does _not_ apply to objects
that are being [interpreted as expressions](#expression-mapping), where this
would be interpreted as an object type attribute named `"//"`.
This special property name can also be used at the root of a JSON-based
configuration file. This can be useful to note which program created the file.
```json
{
"//": "This file is generated by generate-outputs.py. DO NOT HAND-EDIT!",
}
```
@@ -0,0 +1,119 @@
---
layout: "docs"
page_title: "Syntax - Configuration Language"
sidebar_current: configuration-syntax
description: |-
HCL has its own syntax, intended to combine declarative
structure with expressions in a way that is easy for humans to read and
understand.
---
# HCL Configuration Syntax
Other pages in this section have described various configuration constructs
that can appear in HCL. This page describes the lower-level syntax of the
language in more detail, revealing the building blocks that those constructs
are built from.
This page describes the _native syntax_ of HCL, which is a rich language
designed to be easy for humans to read and write. The constructs in HCL can
also be expressed in [JSON syntax](./syntax-json.html), which is harder for
humans to read and edit but easier to generate and parse programmatically.
This low-level syntax of HCL is defined in terms of a syntax called _HCL_,
which is also used by configuration languages in other applications, and in
particular other HashiCorp products. It is not necessary to know all of the
details of HCL in order to use Packer, and so this page summarizes the most
important details. If you are interested, you can find a full definition of HCL
syntax in [the HCL native syntax
specification](https://github.com/hashicorp/hcl/blob/hcl2/hclsyntax/spec.md).
## Arguments and Blocks
HCL syntax is built around two key syntax constructs:
arguments and blocks.
### Arguments
An _argument_ assigns a value to a particular name:
```hcl
image_id = "abc123"
```
The identifier before the equals sign is the _argument name_, and the expression
after the equals sign is the argument's value.
The context where the argument appears determines what value types are valid
(for example, each source type has a schema that defines the types of its
arguments), but many arguments accept arbitrary
[expressions](./expressions.html), which allow the value to
either be specified literally or generated from other values programmatically.
### Blocks
A _block_ is a container for other content:
```hcl
source "amazon-ebs" "example" {
ami_name = "abc123"
tags {
# ...
}
}
```
A block has a _type_ (`source` in this example). Each block type defines
how many _labels_ must follow the type keyword. The `source` block type
expects two labels, which are `amazon-ebs` and `example` in the example above.
A particular block type may have any number of required labels, or it may
require none as with the nested `tags` block type.
After the block type keyword and any labels, the block _body_ is delimited
by the `{` and `}` characters. Within the block body, further arguments
and blocks may be nested, creating a hierarchy of blocks and their associated
arguments.
HCL uses a limited number of _top-level block types,_ which
are blocks that can appear outside of any other block in a configuration file.
Most of Packer's features (including resources, input variables, output
values, data sources, etc.) are implemented as top-level blocks.
## Identifiers
Argument names, block type names, and the names of most Packer-specific
constructs like resources, input variables, etc. are all _identifiers_.
Identifiers can contain letters, digits, underscores (`_`), and hyphens (`-`).
The first character of an identifier must not be a digit, to avoid ambiguity
with literal numbers.
For complete identifier rules, Packer implements
[the Unicode identifier syntax](http://unicode.org/reports/tr31/), extended to
include the ASCII hyphen character `-`.
## Comments
HCL supports three different syntaxes for comments:
* `#` begins a single-line comment, ending at the end of the line.
* `//` also begins a single-line comment, as an alternative to `#`.
* `/*` and `*/` are start and end delimiters for a comment that might span
over multiple lines.
The `#` single-line comment style is the default comment style and should be
used in most cases. Automatic configuration formatting tools may automatically
transform `//` comments into `#` comments, since the double-slash style is
not idiomatic.
## Character Encoding and Line Endings
Packer configuration files must always be UTF-8 encoded. While the
delimiters of the language are all ASCII characters, Packer accepts
non-ASCII characters in identifiers, comments, and string values.
Packer accepts configuration files with either Unix-style line endings
(LF only) or Windows-style line endings (CR then LF), but the idiomatic style
is to use the Unix convention, and so automatic configuration formatting tools
may automatically transform CRLF endings to LF.
@@ -31,7 +31,8 @@ method should do.
``` go
type Builder interface {
Prepare(...interface{}) error
ConfigSpec() hcldec.ObjectSpec
Prepare(...interface{}) ([]string, []string, error)
Run(context.Context, ui Ui, hook Hook) (Artifact, error)
}
```
@@ -36,6 +36,7 @@ explaining what each method should do.
``` go
type PostProcessor interface {
ConfigSpec() hcldec.ObjectSpec
Configure(interface{}) error
PostProcess(context.Context, Ui, Artifact) (a Artifact, keep, mustKeep bool, err error)
}
@@ -35,8 +35,9 @@ explaining what each method should do.
``` go
type Provisioner interface {
ConfigSpec() hcldec.ObjectSpec
Prepare(...interface{}) error
Provision(Ctx, Ui, Communicator, new(interface{})) error
Provision(context.Context, Ui, Communicator, map[string]interface{}) error
}
```
+6 -4
View File
@@ -72,9 +72,9 @@ Here is a full list of the available functions for reference.
"inline": ["echo $TESTVAR"]
},
```
Valid variables to request are: "InstanceID", "CommunicatorHost",
"CommunicatorPort", "CommunicatorUser", "CommunicatorPassword", "ConnType",
"PackerRunUUID", "CommunicatorPublicKey", and "CommunicatorPrivateKey".
Valid variables to request are: "ID", "Host",
"Port", "User", "Password", "ConnType",
"PackerRunUUID", "SSHPublicKey", and "SSHPrivateKey".
Depending on which communicator you are using, some of these values may be
empty -- for example, the public and private keys are unique to the SSH
communicator. InstanceID represents the vm being provisioned. For example,
@@ -84,7 +84,9 @@ Here is a full list of the available functions for reference.
For backwards compatability, `WinRMPassword` is also available through this
engine, though it is no different than using the more general `Password`.
This function is only for use within _provisioners_, and does not yet work
This function is only for use within specific options inside of
_provisioners_ -- these options will be listed as being template engines
in the provisioner documentation. This feature does not yet work
if the provisioners are being used in conjunction with our chroot builders
or with lxc/lxd builders.
@@ -0,0 +1,44 @@
---
layout: guides
page_title: Generating code for config spec.
sidebar_current: hcl-component-object-spec
description: |-
Learn how to generate the HCL2 configuration of your component easily.
---
# Auto Generate the HCL2 code of a plugin
From v1.5, Packer can be configured using HCL2. Because Packer has so many
builders, provisioner & post-processors, we relied on code generation to
iterate more easily. The good new is that you can benefit from this code
generator to get the HCL2 spec code of your component simply. It's a Go binary
package and is located in [`cmd/mapstructure-to-hcl2`](https://github.com/hashicorp/packer/tree/master/cmd/mapstructure-to-hcl2).
Say you want to configure the `Config` struct of a `Builder` in a package
located in `my/example-plugin/config.go`. Here are some simple steps you can
follow to make it HCL2 enabled:
* run `go install github.com/hashicorp/packer/cmd/mapstructure-to-hcl2`
* Add `//go:generate mapstructure-to-hcl2 -type Config` at the top of
`config.go`
* run `go generate ./my/example-plugin/...`
This will generate a `my/example-plugin/config.hcl2spec.go` file containing
the configuration fields of `Config`.
* Make sure that all the nested structs of `Config` are also auto generated the
same way.
* Now we only need to make Builder implement the interface by adding the
following snippet:
```go
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
```
From now on every time you add or change a field of Config you will need to
run the `go generate` command again.
A good example of this is the [Config struct of the amazon-ebs builder](https://github.com/hashicorp/packer/blob/master/builder/amazon/ebs/builder.go)
@@ -1,13 +1,13 @@
---
layout: guides
page_title: Transforming Packer v1 files for Packer v1.5.0
sidebar_current: hcl
sidebar_current: hcl-from-json-v1
description: |-
Learn how to manually move from a Packer v1 working JSON build file to a
working v1.5.0 HCL file.
---
# Transforming Packer v1 files for Packer v1.5
# Transforming Packer v1 config files to HCL2 for Packer v1.5
-> **Note:** Starting from version **1.5.0** Packer can read HCL2 files.
@@ -50,3 +50,41 @@ It could be super handy for a boot_command.
EOF
}
```
## Building blocks can be split in files
Currently Packer offers the `source` and the `build` root blocks. These two
building blocks can be defined in any order and a `build` can import one or more
`source`. Usually a `source` defines what we currently call a builder and a
`build` can apply multiple provisioning steps to a source. For example:
```hcl
# folder/sources.pkr.hcl
source "amazon-ebs" "example-1" {
ami_name = "example-1-ami"
}
source "virtualbox-iso" "example-2" {
boot_command = <<EOF
<esc><esc><enter><wait>
/install/vmlinuz noapic
...
EOF
}
```
```hcl
# folder/build.pkr.hcl
build {
sources = [
"source.amazon-ebs.example-1",
"source.virtualbox-iso.example-2"
]
provisioner "shell" {
inline = [
"echo it's alive !"
]
}
}
```
+23 -2
View File
@@ -1,9 +1,24 @@
<% wrap_layout :inner do %>
<% content_for :sidebar do %>
<ul class="nav docs-sidenav">
<li<%= sidebar_current("docs-install") %>>
<a href="/docs/install/index.html">Installing Packer</a>
<li<%= sidebar_current("configuration") %>>
<a href="/docs/configuration/from-1.5/index.html">v1.5 Configuration Language</a>
<ul class="nav">
<li<%= sidebar_current("configuration-syntax") %>>
<a href="/docs/configuration/from-1.5/syntax.html">Syntax</a>
</li>
<li<%= sidebar_current("configuration-expressions") %>>
<a href="/docs/configuration/from-1.5/expressions.html">Expressions</a>
</li>
<li<%= sidebar_current("configuration-json-syntax") %>>
<a href="/docs/configuration/from-1.5/syntax-json.html">JSON Syntax</a>
</li>
</ul>
</li>
<hr>
<li><a href="/docs/basics/terminology.html">Terminology</a></li>
<li<%= sidebar_current("docs-commands") %>>
@@ -384,6 +399,12 @@
<hr>
<li<%= sidebar_current("docs-install") %>>
<a href="/docs/install/index.html">Installing Packer</a>
</li>
<hr>
<li<%= sidebar_current("docs-extending") %>>
<a href="/docs/extending/index.html">Extending Packer</a>
<ul class="nav">
+3
View File
@@ -7,6 +7,9 @@
<li<%= sidebar_current("hcl-from-json-v1") %>>
<a href="/guides/hcl/from-json-v1">from JSON v1</a>
</li>
<li<%= sidebar_current("hcl-component-object-spec") %>>
<a href="/guides/hcl/component-object-spec">Making a plugin HCL2 enabled</a>
</li>
</ul>
</li>
<li<%= sidebar_current("automatic-operating-system-installs") %>>
@@ -3,6 +3,9 @@
- `skip_region_validation` (bool) - The region validation can be skipped if this value is true, the default
value is false.
- `skip_image_validation` (bool) - The image validation can be skipped if this value is true, the default
value is false.
- `security_token` (string) - STS access token, can be set through template or by exporting as
environment variable such as `export SECURITY_TOKEN=value`.
@@ -10,3 +10,5 @@
- [Vultr builder](https://github.com/vultr/packer-builder-vultr) - A builder
for creating [Vultr](https://www.vultr.com/) snapshots.
- [Huawei Cloud ECS builder](https://github.com/huaweicloud/packer-builder-huaweicloud-ecs) - Plugin for creating [Huawei Cloud ECS](https://www.huaweicloud.com/intl/en-us/) images.
@@ -46,7 +46,8 @@
use this option with a key pair already configured in the source AMI,
leave the `ssh_keypair_name` blank. To associate an existing key pair in
AWS with the source instance, set the `ssh_keypair_name` field to the
name of the key pair.
name of the key pair. The environment variable `SSH_AUTH_SOCK` must be
set for this option to work properly.
- `ssh_disable_agent_forwarding` (bool) - If true, SSH agent forwarding will be disabled. Defaults to `false`.