Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
packer
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kristopher Ruzic
packer
Commits
f2f8ad16
Commit
f2f8ad16
authored
Jun 16, 2015
by
Chris Bednarski
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into f-file-builder
parents
aea70d5a
95d4b845
Changes
28
Show whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
452 additions
and
88 deletions
+452
-88
CHANGELOG.md
CHANGELOG.md
+10
-0
Makefile
Makefile
+7
-1
builder/amazon/common/run_config.go
builder/amazon/common/run_config.go
+5
-3
builder/amazon/common/step_key_pair.go
builder/amazon/common/step_key_pair.go
+14
-9
builder/amazon/common/step_run_source_instance.go
builder/amazon/common/step_run_source_instance.go
+1
-1
builder/amazon/ebs/builder.go
builder/amazon/ebs/builder.go
+5
-4
builder/amazon/instance/builder.go
builder/amazon/instance/builder.go
+5
-4
builder/vmware/common/step_upload_tools.go
builder/vmware/common/step_upload_tools.go
+4
-4
builder/vmware/iso/builder.go
builder/vmware/iso/builder.go
+15
-14
builder/vmware/iso/step_create_vmx.go
builder/vmware/iso/step_create_vmx.go
+24
-2
common/step_provision.go
common/step_provision.go
+4
-2
communicator/ssh/communicator.go
communicator/ssh/communicator.go
+52
-2
communicator/winrm/communicator.go
communicator/winrm/communicator.go
+1
-1
packer/build_test.go
packer/build_test.go
+1
-1
packer/builder_mock.go
packer/builder_mock.go
+1
-1
packer/provisioner.go
packer/provisioner.go
+12
-0
packer/provisioner_test.go
packer/provisioner_test.go
+21
-3
provisioner/chef-client/provisioner.go
provisioner/chef-client/provisioner.go
+53
-21
provisioner/file/provisioner.go
provisioner/file/provisioner.go
+43
-0
provisioner/puppet-masterless/provisioner.go
provisioner/puppet-masterless/provisioner.go
+18
-1
provisioner/puppet-masterless/provisioner_test.go
provisioner/puppet-masterless/provisioner_test.go
+44
-0
provisioner/shell/provisioner.go
provisioner/shell/provisioner.go
+16
-3
website/source/docs/builders/amazon-ebs.html.markdown
website/source/docs/builders/amazon-ebs.html.markdown
+30
-5
website/source/docs/builders/amazon-instance.html.markdown
website/source/docs/builders/amazon-instance.html.markdown
+28
-5
website/source/docs/builders/parallels-iso.html.markdown
website/source/docs/builders/parallels-iso.html.markdown
+1
-1
website/source/docs/provisioners/chef-client.html.markdown
website/source/docs/provisioners/chef-client.html.markdown
+12
-0
website/source/docs/provisioners/file.html.markdown
website/source/docs/provisioners/file.html.markdown
+4
-0
website/source/docs/provisioners/puppet-masterless.html.markdown
.../source/docs/provisioners/puppet-masterless.html.markdown
+21
-0
No files found.
CHANGELOG.md
View file @
f2f8ad16
...
@@ -24,6 +24,8 @@ FEATURES:
...
@@ -24,6 +24,8 @@ FEATURES:
to allow access to remote servers such as private git repos. [GH-1066]
to allow access to remote servers such as private git repos. [GH-1066]
*
**Docker builder supports SSH**
: The Docker builder now supports containers
*
**Docker builder supports SSH**
: The Docker builder now supports containers
with SSH, just set
`communicator`
to "ssh" [GH-2244]
with SSH, just set
`communicator`
to "ssh" [GH-2244]
*
**File provisioner can download**
: The file provisioner can now download
files out of the build process. [GH-1909]
*
**New config function: `build_name`**
: The name of the currently running
*
**New config function: `build_name`**
: The name of the currently running
build. [GH-2232]
build. [GH-2232]
*
**New config function: `build_type`**
: The type of the currently running
*
**New config function: `build_type`**
: The type of the currently running
...
@@ -39,6 +41,7 @@ IMPROVEMENTS:
...
@@ -39,6 +41,7 @@ IMPROVEMENTS:
*
builder/amazon: Add
`force_deregister`
option for automatic AMI
*
builder/amazon: Add
`force_deregister`
option for automatic AMI
deregistration [GH-2221]
deregistration [GH-2221]
*
builder/amazon: Now applies tags to EBS snapshots [GH-2212]
*
builder/amazon: Now applies tags to EBS snapshots [GH-2212]
*
builder/amazon: Support custom keypairs [GH-1837]
*
builder/digitalocean: Save SSH key to pwd if debug mode is on. [GH-1829]
*
builder/digitalocean: Save SSH key to pwd if debug mode is on. [GH-1829]
*
builder/digitalocean: User data support [GH-2113]
*
builder/digitalocean: User data support [GH-2113]
*
builder/parallels: Support Parallels Desktop 11 [GH-2199]
*
builder/parallels: Support Parallels Desktop 11 [GH-2199]
...
@@ -55,12 +58,16 @@ IMPROVEMENTS:
...
@@ -55,12 +58,16 @@ IMPROVEMENTS:
automatic port forward for SSH and to use the guest port directly. [GH-1078]
automatic port forward for SSH and to use the guest port directly. [GH-1078]
*
builder/virtualbox: Added SCSI support
*
builder/virtualbox: Added SCSI support
*
builder/vmware: Support for additional disks [GH-1382]
*
builder/vmware: Support for additional disks [GH-1382]
*
builder/vmware: Can now customize the template used for adding disks [GH-2254]
*
command/fix: After fixing, the template is validated [GH-2228]
*
command/fix: After fixing, the template is validated [GH-2228]
*
command/push: Add
`-name`
flag for specifying name from CLI [GH-2042]
*
command/push: Add
`-name`
flag for specifying name from CLI [GH-2042]
*
command/push: Push configuration in templates supports variables [GH-1861]
*
command/push: Push configuration in templates supports variables [GH-1861]
*
post-processor/docker-save: Can be chained [GH-2179]
*
post-processor/docker-save: Can be chained [GH-2179]
*
post-processor/docker-tag: Support
`force`
option [GH-2055]
*
post-processor/docker-tag: Support
`force`
option [GH-2055]
*
post-processor/docker-tag: Can be chained [GH-2179]
*
post-processor/docker-tag: Can be chained [GH-2179]
*
provisioner/puppet-masterless:
`working_directory`
option [GH-1831]
*
provisioner/puppet-masterless:
`packer_build_name`
and
`packer_build_type`
are default facts. [GH-1878]
BUG FIXES:
BUG FIXES:
...
@@ -121,11 +128,14 @@ BUG FIXES:
...
@@ -121,11 +128,14 @@ BUG FIXES:
*
post-processor/atlas: Fix index out of range panic [GH-1959]
*
post-processor/atlas: Fix index out of range panic [GH-1959]
*
post-processor/vagrant-cloud: Fixed failing on response
*
post-processor/vagrant-cloud: Fixed failing on response
*
post-processor/vagrant-cloud: Don't delete version on error [GH-2014]
*
post-processor/vagrant-cloud: Don't delete version on error [GH-2014]
*
provisioner/chef-client: Fix permissions issues on default dir [GH-2255]
*
provisioner/chef-client: Node cleanup works now. [GH-2257]
*
provisioner/puppet-masterless: Allow manifest_file to be a directory
*
provisioner/puppet-masterless: Allow manifest_file to be a directory
*
provisioner/salt-masterless: Add
`--retcode-passthrough`
to salt-call
*
provisioner/salt-masterless: Add
`--retcode-passthrough`
to salt-call
*
provisioner/shell: chmod executable script to 0755, not 0777 [GH-1708]
*
provisioner/shell: chmod executable script to 0755, not 0777 [GH-1708]
*
provisioner/shell: inline commands failing will fail the provisioner [GH-2069]
*
provisioner/shell: inline commands failing will fail the provisioner [GH-2069]
*
provisioner/shell: single quotes in env vars are escaped [GH-2229]
*
provisioner/shell: single quotes in env vars are escaped [GH-2229]
*
provisioner/shell: Temporary file is deleted after run [GH-2259]
## 0.7.5 (December 9, 2014)
## 0.7.5 (December 9, 2014)
...
...
Makefile
View file @
f2f8ad16
...
@@ -31,7 +31,13 @@ testrace:
...
@@ -31,7 +31,13 @@ testrace:
go
test
-race
$(TEST)
$(TESTARGS)
go
test
-race
$(TEST)
$(TESTARGS)
updatedeps
:
updatedeps
:
go get
-d
-v
-p
2 ./...
go get
-u
github.com/mitchellh/gox
go get
-u
golang.org/x/tools/cmd/stringer
go list ./...
\
| xargs go list
-f
'{{join .Deps "\n"}}'
\
|
grep
-v
github.com/mitchellh/packer
\
|
sort
-u
\
| xargs go get
-f
-u
-v
vet
:
vet
:
@
go tool vet 2>/dev/null
;
if
[
$$
?
-eq
3
]
;
then
\
@
go tool vet 2>/dev/null
;
if
[
$$
?
-eq
3
]
;
then
\
...
...
builder/amazon/common/run_config.go
View file @
f2f8ad16
...
@@ -33,11 +33,13 @@ type RunConfig struct {
...
@@ -33,11 +33,13 @@ type RunConfig struct {
// Communicator settings
// Communicator settings
Comm
communicator
.
Config
`mapstructure:",squash"`
Comm
communicator
.
Config
`mapstructure:",squash"`
SSHKeyPairName
string
`mapstructure:"ssh_keypair_name"`
SSHPrivateIp
bool
`mapstructure:"ssh_private_ip"`
SSHPrivateIp
bool
`mapstructure:"ssh_private_ip"`
}
}
func
(
c
*
RunConfig
)
Prepare
(
ctx
*
interpolate
.
Context
)
[]
error
{
func
(
c
*
RunConfig
)
Prepare
(
ctx
*
interpolate
.
Context
)
[]
error
{
if
c
.
TemporaryKeyPairName
==
""
{
// if we are not given an explicit keypairname, create a temporary one
if
c
.
SSHKeyPairName
==
""
{
c
.
TemporaryKeyPairName
=
fmt
.
Sprintf
(
c
.
TemporaryKeyPairName
=
fmt
.
Sprintf
(
"packer %s"
,
uuid
.
TimeOrderedUUID
())
"packer %s"
,
uuid
.
TimeOrderedUUID
())
}
}
...
...
builder/amazon/common/step_key_pair.go
View file @
f2f8ad16
...
@@ -14,6 +14,7 @@ import (
...
@@ -14,6 +14,7 @@ import (
type
StepKeyPair
struct
{
type
StepKeyPair
struct
{
Debug
bool
Debug
bool
DebugKeyPath
string
DebugKeyPath
string
TemporaryKeyPairName
string
KeyPairName
string
KeyPairName
string
PrivateKeyFile
string
PrivateKeyFile
string
...
@@ -22,7 +23,9 @@ type StepKeyPair struct {
...
@@ -22,7 +23,9 @@ type StepKeyPair struct {
func
(
s
*
StepKeyPair
)
Run
(
state
multistep
.
StateBag
)
multistep
.
StepAction
{
func
(
s
*
StepKeyPair
)
Run
(
state
multistep
.
StateBag
)
multistep
.
StepAction
{
if
s
.
PrivateKeyFile
!=
""
{
if
s
.
PrivateKeyFile
!=
""
{
s
.
keyName
=
""
if
s
.
KeyPairName
!=
""
{
s
.
keyName
=
s
.
KeyPairName
// need to get from config
}
privateKeyBytes
,
err
:=
ioutil
.
ReadFile
(
s
.
PrivateKeyFile
)
privateKeyBytes
,
err
:=
ioutil
.
ReadFile
(
s
.
PrivateKeyFile
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -30,7 +33,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -30,7 +33,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
state
.
Put
(
"keyPair"
,
""
)
state
.
Put
(
"keyPair"
,
s
.
keyName
)
state
.
Put
(
"privateKey"
,
string
(
privateKeyBytes
))
state
.
Put
(
"privateKey"
,
string
(
privateKeyBytes
))
return
multistep
.
ActionContinue
return
multistep
.
ActionContinue
...
@@ -39,7 +42,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -39,7 +42,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
ec2conn
:=
state
.
Get
(
"ec2"
)
.
(
*
ec2
.
EC2
)
ec2conn
:=
state
.
Get
(
"ec2"
)
.
(
*
ec2
.
EC2
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
.
Say
(
fmt
.
Sprintf
(
"Creating temporary keypair: %s"
,
s
.
KeyPairName
))
ui
.
Say
(
fmt
.
Sprintf
(
"Creating temporary keypair: %s"
,
s
.
Temporary
KeyPairName
))
keyResp
,
err
:=
ec2conn
.
CreateKeyPair
(
&
ec2
.
CreateKeyPairInput
{
KeyName
:
&
s
.
KeyPairName
})
keyResp
,
err
:=
ec2conn
.
CreateKeyPair
(
&
ec2
.
CreateKeyPairInput
{
KeyName
:
&
s
.
KeyPairName
})
if
err
!=
nil
{
if
err
!=
nil
{
state
.
Put
(
"error"
,
fmt
.
Errorf
(
"Error creating temporary keypair: %s"
,
err
))
state
.
Put
(
"error"
,
fmt
.
Errorf
(
"Error creating temporary keypair: %s"
,
err
))
...
@@ -47,7 +50,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -47,7 +50,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
}
}
// Set the keyname so we know to delete it later
// Set the keyname so we know to delete it later
s
.
keyName
=
s
.
KeyPairName
s
.
keyName
=
s
.
Temporary
KeyPairName
// Set some state data for use in future steps
// Set some state data for use in future steps
state
.
Put
(
"keyPair"
,
s
.
keyName
)
state
.
Put
(
"keyPair"
,
s
.
keyName
)
...
@@ -84,7 +87,9 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -84,7 +87,9 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
func
(
s
*
StepKeyPair
)
Cleanup
(
state
multistep
.
StateBag
)
{
func
(
s
*
StepKeyPair
)
Cleanup
(
state
multistep
.
StateBag
)
{
// If no key name is set, then we never created it, so just return
// If no key name is set, then we never created it, so just return
if
s
.
keyName
==
""
{
// If we used an SSH private key file, do not go about deleting
// keypairs
if
s
.
PrivateKeyFile
!=
""
{
return
return
}
}
...
...
builder/amazon/common/step_run_source_instance.go
View file @
f2f8ad16
...
@@ -245,7 +245,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
...
@@ -245,7 +245,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
}
}
latestInstance
,
err
:=
WaitForState
(
&
stateChange
)
latestInstance
,
err
:=
WaitForState
(
&
stateChange
)
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error waiting for instance (%s) to become ready: %s"
,
*
s
.
instance
.
InstanceID
,
err
)
err
:=
fmt
.
Errorf
(
"Error waiting for instance (%s) to become ready: %s"
,
instanceId
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
ui
.
Error
(
err
.
Error
())
ui
.
Error
(
err
.
Error
())
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
...
...
builder/amazon/ebs/builder.go
View file @
f2f8ad16
...
@@ -91,6 +91,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
...
@@ -91,6 +91,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Debug
:
b
.
config
.
PackerDebug
,
Debug
:
b
.
config
.
PackerDebug
,
DebugKeyPath
:
fmt
.
Sprintf
(
"ec2_%s.pem"
,
b
.
config
.
PackerBuildName
),
DebugKeyPath
:
fmt
.
Sprintf
(
"ec2_%s.pem"
,
b
.
config
.
PackerBuildName
),
KeyPairName
:
b
.
config
.
TemporaryKeyPairName
,
KeyPairName
:
b
.
config
.
TemporaryKeyPairName
,
TemporaryKeyPairName
:
b
.
config
.
TemporaryKeyPairName
,
PrivateKeyFile
:
b
.
config
.
RunConfig
.
Comm
.
SSHPrivateKey
,
PrivateKeyFile
:
b
.
config
.
RunConfig
.
Comm
.
SSHPrivateKey
,
},
},
&
awscommon
.
StepSecurityGroup
{
&
awscommon
.
StepSecurityGroup
{
...
...
builder/amazon/instance/builder.go
View file @
f2f8ad16
...
@@ -181,6 +181,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
...
@@ -181,6 +181,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
DebugKeyPath
:
fmt
.
Sprintf
(
"ec2_%s.pem"
,
b
.
config
.
PackerBuildName
),
DebugKeyPath
:
fmt
.
Sprintf
(
"ec2_%s.pem"
,
b
.
config
.
PackerBuildName
),
KeyPairName
:
b
.
config
.
TemporaryKeyPairName
,
KeyPairName
:
b
.
config
.
TemporaryKeyPairName
,
PrivateKeyFile
:
b
.
config
.
RunConfig
.
Comm
.
SSHPrivateKey
,
PrivateKeyFile
:
b
.
config
.
RunConfig
.
Comm
.
SSHPrivateKey
,
TemporaryKeyPairName
:
b
.
config
.
TemporaryKeyPairName
,
},
},
&
awscommon
.
StepSecurityGroup
{
&
awscommon
.
StepSecurityGroup
{
CommConfig
:
&
b
.
config
.
RunConfig
.
Comm
,
CommConfig
:
&
b
.
config
.
RunConfig
.
Comm
,
...
...
builder/vmware/common/step_upload_tools.go
View file @
f2f8ad16
...
@@ -23,6 +23,10 @@ type StepUploadTools struct {
...
@@ -23,6 +23,10 @@ type StepUploadTools struct {
func
(
c
*
StepUploadTools
)
Run
(
state
multistep
.
StateBag
)
multistep
.
StepAction
{
func
(
c
*
StepUploadTools
)
Run
(
state
multistep
.
StateBag
)
multistep
.
StepAction
{
driver
:=
state
.
Get
(
"driver"
)
.
(
Driver
)
driver
:=
state
.
Get
(
"driver"
)
.
(
Driver
)
if
c
.
ToolsUploadFlavor
==
""
{
return
multistep
.
ActionContinue
}
if
c
.
RemoteType
==
"esx5"
{
if
c
.
RemoteType
==
"esx5"
{
if
err
:=
driver
.
ToolsInstall
();
err
!=
nil
{
if
err
:=
driver
.
ToolsInstall
();
err
!=
nil
{
state
.
Put
(
"error"
,
fmt
.
Errorf
(
"Couldn't mount VMware tools ISO. Please check the 'guest_os_type' in your template.json."
))
state
.
Put
(
"error"
,
fmt
.
Errorf
(
"Couldn't mount VMware tools ISO. Please check the 'guest_os_type' in your template.json."
))
...
@@ -30,10 +34,6 @@ func (c *StepUploadTools) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -30,10 +34,6 @@ func (c *StepUploadTools) Run(state multistep.StateBag) multistep.StepAction {
return
multistep
.
ActionContinue
return
multistep
.
ActionContinue
}
}
if
c
.
ToolsUploadFlavor
==
""
{
return
multistep
.
ActionContinue
}
comm
:=
state
.
Get
(
"communicator"
)
.
(
packer
.
Communicator
)
comm
:=
state
.
Get
(
"communicator"
)
.
(
packer
.
Communicator
)
tools_source
:=
state
.
Get
(
"tools_upload_source"
)
.
(
string
)
tools_source
:=
state
.
Get
(
"tools_upload_source"
)
.
(
string
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
...
...
builder/vmware/iso/builder.go
100644 → 100755
View file @
f2f8ad16
...
@@ -50,6 +50,7 @@ type Config struct {
...
@@ -50,6 +50,7 @@ type Config struct {
BootCommand
[]
string
`mapstructure:"boot_command"`
BootCommand
[]
string
`mapstructure:"boot_command"`
SkipCompaction
bool
`mapstructure:"skip_compaction"`
SkipCompaction
bool
`mapstructure:"skip_compaction"`
VMXTemplatePath
string
`mapstructure:"vmx_template_path"`
VMXTemplatePath
string
`mapstructure:"vmx_template_path"`
VMXDiskTemplatePath
string
`mapstructure:"vmx_disk_template_path"`
RemoteType
string
`mapstructure:"remote_type"`
RemoteType
string
`mapstructure:"remote_type"`
RemoteDatastore
string
`mapstructure:"remote_datastore"`
RemoteDatastore
string
`mapstructure:"remote_datastore"`
...
...
builder/vmware/iso/step_create_vmx.go
100644 → 100755
View file @
f2f8ad16
...
@@ -76,7 +76,29 @@ func (s *stepCreateVMX) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -76,7 +76,29 @@ func (s *stepCreateVMX) Run(state multistep.StateBag) multistep.StepAction {
DiskName
:
config
.
DiskName
,
DiskName
:
config
.
DiskName
,
}
}
diskTemplate
,
err
:=
interpolate
.
Render
(
DefaultAdditionalDiskTemplate
,
&
ctx
)
diskTemplate
:=
DefaultAdditionalDiskTemplate
if
config
.
VMXDiskTemplatePath
!=
""
{
f
,
err
:=
os
.
Open
(
config
.
VMXDiskTemplatePath
)
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error reading VMX disk template: %s"
,
err
)
state
.
Put
(
"error"
,
err
)
ui
.
Error
(
err
.
Error
())
return
multistep
.
ActionHalt
}
defer
f
.
Close
()
rawBytes
,
err
:=
ioutil
.
ReadAll
(
f
)
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error reading VMX disk template: %s"
,
err
)
state
.
Put
(
"error"
,
err
)
ui
.
Error
(
err
.
Error
())
return
multistep
.
ActionHalt
}
diskTemplate
=
string
(
rawBytes
)
}
diskContents
,
err
:=
interpolate
.
Render
(
diskTemplate
,
&
ctx
)
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error preparing VMX template for additional disk: %s"
,
err
)
err
:=
fmt
.
Errorf
(
"Error preparing VMX template for additional disk: %s"
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
...
@@ -84,7 +106,7 @@ func (s *stepCreateVMX) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -84,7 +106,7 @@ func (s *stepCreateVMX) Run(state multistep.StateBag) multistep.StepAction {
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
vmxTemplate
+=
disk
Template
vmxTemplate
+=
disk
Contents
}
}
}
}
...
...
common/step_provision.go
View file @
f2f8ad16
...
@@ -23,9 +23,11 @@ type StepProvision struct {
...
@@ -23,9 +23,11 @@ type StepProvision struct {
func
(
s
*
StepProvision
)
Run
(
state
multistep
.
StateBag
)
multistep
.
StepAction
{
func
(
s
*
StepProvision
)
Run
(
state
multistep
.
StateBag
)
multistep
.
StepAction
{
comm
:=
s
.
Comm
comm
:=
s
.
Comm
if
comm
==
nil
{
if
comm
==
nil
{
comm
=
state
.
Get
(
"communicator"
)
.
(
packer
.
Communicator
)
raw
,
ok
:=
state
.
Get
(
"communicator"
)
.
(
packer
.
Communicator
)
if
ok
{
comm
=
raw
.
(
packer
.
Communicator
)
}
}
}
hook
:=
state
.
Get
(
"hook"
)
.
(
packer
.
Hook
)
hook
:=
state
.
Get
(
"hook"
)
.
(
packer
.
Hook
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
...
...
communicator/ssh/communicator.go
View file @
f2f8ad16
...
@@ -14,6 +14,7 @@ import (
...
@@ -14,6 +14,7 @@ import (
"net"
"net"
"os"
"os"
"path/filepath"
"path/filepath"
"strconv"
"sync"
"sync"
)
)
...
@@ -171,8 +172,57 @@ func (c *comm) UploadDir(dst string, src string, excl []string) error {
...
@@ -171,8 +172,57 @@ func (c *comm) UploadDir(dst string, src string, excl []string) error {
return
c
.
scpSession
(
"scp -rvt "
+
dst
,
scpFunc
)
return
c
.
scpSession
(
"scp -rvt "
+
dst
,
scpFunc
)
}
}
func
(
c
*
comm
)
Download
(
string
,
io
.
Writer
)
error
{
func
(
c
*
comm
)
Download
(
path
string
,
output
io
.
Writer
)
error
{
panic
(
"not implemented yet"
)
scpFunc
:=
func
(
w
io
.
Writer
,
stdoutR
*
bufio
.
Reader
)
error
{
fmt
.
Fprint
(
w
,
"
\x00
"
)
// read file info
fi
,
err
:=
stdoutR
.
ReadString
(
'\n'
)
if
err
!=
nil
{
return
err
}
if
len
(
fi
)
<
0
{
return
fmt
.
Errorf
(
"empty response from server"
)
}
switch
fi
[
0
]
{
case
'\x01'
,
'\x02'
:
return
fmt
.
Errorf
(
"%s"
,
fi
[
1
:
len
(
fi
)])
case
'C'
:
case
'D'
:
return
fmt
.
Errorf
(
"remote file is directory"
)
default
:
return
fmt
.
Errorf
(
"unexpected server response (%x)"
,
fi
[
0
])
}
var
mode
string
var
size
int64
n
,
err
:=
fmt
.
Sscanf
(
fi
,
"%6s %d "
,
&
mode
,
&
size
)
if
err
!=
nil
||
n
!=
2
{
return
fmt
.
Errorf
(
"can't parse server response (%s)"
,
fi
)
}
if
size
<
0
{
return
fmt
.
Errorf
(
"negative file size"
)
}
fmt
.
Fprint
(
w
,
"
\x00
"
)
if
_
,
err
:=
io
.
CopyN
(
output
,
stdoutR
,
size
);
err
!=
nil
{
return
err
}
fmt
.
Fprint
(
w
,
"
\x00
"
)
if
err
:=
checkSCPStatus
(
stdoutR
);
err
!=
nil
{
return
err
}
return
nil
}
return
c
.
scpSession
(
"scp -vf "
+
strconv
.
Quote
(
path
),
scpFunc
)
}
}
func
(
c
*
comm
)
newSession
()
(
session
*
ssh
.
Session
,
err
error
)
{
func
(
c
*
comm
)
newSession
()
(
session
*
ssh
.
Session
,
err
error
)
{
...
...
communicator/winrm/communicator.go
View file @
f2f8ad16
...
@@ -113,7 +113,7 @@ func (c *Communicator) UploadDir(dst string, src string, exclude []string) error
...
@@ -113,7 +113,7 @@ func (c *Communicator) UploadDir(dst string, src string, exclude []string) error
}
}
func
(
c
*
Communicator
)
Download
(
src
string
,
dst
io
.
Writer
)
error
{
func
(
c
*
Communicator
)
Download
(
src
string
,
dst
io
.
Writer
)
error
{
panic
(
"download not implemented
"
)
return
fmt
.
Errorf
(
"WinRM doesn't support download.
"
)
}
}
func
(
c
*
Communicator
)
newCopyClient
()
(
*
winrmcp
.
Winrmcp
,
error
)
{
func
(
c
*
Communicator
)
newCopyClient
()
(
*
winrmcp
.
Winrmcp
,
error
)
{
...
...
packer/build_test.go
View file @
f2f8ad16
...
@@ -202,7 +202,7 @@ func TestBuild_Run(t *testing.T) {
...
@@ -202,7 +202,7 @@ func TestBuild_Run(t *testing.T) {
}
}
// Verify provisioners run
// Verify provisioners run
dispatchHook
.
Run
(
HookProvision
,
nil
,
n
il
,
42
)
dispatchHook
.
Run
(
HookProvision
,
nil
,
n
ew
(
MockCommunicator
)
,
42
)
prov
:=
build
.
provisioners
[
0
]
.
provisioner
.
(
*
MockProvisioner
)
prov
:=
build
.
provisioners
[
0
]
.
provisioner
.
(
*
MockProvisioner
)
if
!
prov
.
ProvCalled
{
if
!
prov
.
ProvCalled
{
t
.
Fatal
(
"should be called"
)
t
.
Fatal
(
"should be called"
)
...
...
packer/builder_mock.go
View file @
f2f8ad16
...
@@ -43,7 +43,7 @@ func (tb *MockBuilder) Run(ui Ui, h Hook, c Cache) (Artifact, error) {
...
@@ -43,7 +43,7 @@ func (tb *MockBuilder) Run(ui Ui, h Hook, c Cache) (Artifact, error) {
}
}
if
h
!=
nil
{
if
h
!=
nil
{
if
err
:=
h
.
Run
(
HookProvision
,
ui
,
n
il
,
nil
);
err
!=
nil
{
if
err
:=
h
.
Run
(
HookProvision
,
ui
,
n
ew
(
MockCommunicator
)
,
nil
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
}
}
...
...
packer/provisioner.go
View file @
f2f8ad16
...
@@ -38,6 +38,18 @@ type ProvisionHook struct {
...
@@ -38,6 +38,18 @@ type ProvisionHook struct {
// Runs the provisioners in order.
// Runs the provisioners in order.
func
(
h
*
ProvisionHook
)
Run
(
name
string
,
ui
Ui
,
comm
Communicator
,
data
interface
{})
error
{
func
(
h
*
ProvisionHook
)
Run
(
name
string
,
ui
Ui
,
comm
Communicator
,
data
interface
{})
error
{
// Shortcut
if
len
(
h
.
Provisioners
)
==
0
{
return
nil
}
if
comm
==
nil
{
return
fmt
.
Errorf
(
"No communicator found for provisioners! This is usually because the
\n
"
+
"`communicator` config was set to
\"
none
\"
. If you have any provisioners
\n
"
+
"then a communicator is required. Please fix this to continue."
)
}
defer
func
()
{
defer
func
()
{
h
.
lock
.
Lock
()
h
.
lock
.
Lock
()
defer
h
.
lock
.
Unlock
()
defer
h
.
lock
.
Unlock
()
...
...
packer/provisioner_test.go
View file @
f2f8ad16
...
@@ -19,7 +19,7 @@ func TestProvisionHook(t *testing.T) {
...
@@ -19,7 +19,7 @@ func TestProvisionHook(t *testing.T) {
pB
:=
&
MockProvisioner
{}
pB
:=
&
MockProvisioner
{}
ui
:=
testUi
()
ui
:=
testUi
()
var
comm
Communicator
=
n
il
var
comm
Communicator
=
n
ew
(
MockCommunicator
)
var
data
interface
{}
=
nil
var
data
interface
{}
=
nil
hook
:=
&
ProvisionHook
{
hook
:=
&
ProvisionHook
{
...
@@ -37,6 +37,24 @@ func TestProvisionHook(t *testing.T) {
...
@@ -37,6 +37,24 @@ func TestProvisionHook(t *testing.T) {
}
}
}
}
func
TestProvisionHook_nilComm
(
t
*
testing
.
T
)
{
pA
:=
&
MockProvisioner
{}
pB
:=
&
MockProvisioner
{}
ui
:=
testUi
()
var
comm
Communicator
=
nil
var
data
interface
{}
=
nil
hook
:=
&
ProvisionHook
{
Provisioners
:
[]
Provisioner
{
pA
,
pB
},
}
err
:=
hook
.
Run
(
"foo"
,
ui
,
comm
,
data
)
if
err
==
nil
{
t
.
Fatal
(
"should error"
)
}
}
func
TestProvisionHook_cancel
(
t
*
testing
.
T
)
{
func
TestProvisionHook_cancel
(
t
*
testing
.
T
)
{
var
lock
sync
.
Mutex
var
lock
sync
.
Mutex
order
:=
make
([]
string
,
0
,
2
)
order
:=
make
([]
string
,
0
,
2
)
...
@@ -59,7 +77,7 @@ func TestProvisionHook_cancel(t *testing.T) {
...
@@ -59,7 +77,7 @@ func TestProvisionHook_cancel(t *testing.T) {
finished
:=
make
(
chan
struct
{})
finished
:=
make
(
chan
struct
{})
go
func
()
{
go
func
()
{
hook
.
Run
(
"foo"
,
nil
,
n
il
,
nil
)
hook
.
Run
(
"foo"
,
nil
,
n
ew
(
MockCommunicator
)
,
nil
)
close
(
finished
)
close
(
finished
)
}()
}()
...
@@ -74,7 +92,7 @@ func TestProvisionHook_cancel(t *testing.T) {
...
@@ -74,7 +92,7 @@ func TestProvisionHook_cancel(t *testing.T) {
<-
finished
<-
finished
// Verify order
// Verify order
if
order
[
0
]
!=
"cancel"
||
order
[
1
]
!=
"prov"
{
if
len
(
order
)
!=
2
||
order
[
0
]
!=
"cancel"
||
order
[
1
]
!=
"prov"
{
t
.
Fatalf
(
"bad: %#v"
,
order
)
t
.
Fatalf
(
"bad: %#v"
,
order
)
}
}
}
}
...
...
provisioner/chef-client/provisioner.go
View file @
f2f8ad16
...
@@ -9,7 +9,6 @@ import (
...
@@ -9,7 +9,6 @@ import (
"fmt"
"fmt"
"io/ioutil"
"io/ioutil"
"os"
"os"
"os/exec"
"path/filepath"
"path/filepath"
"strings"
"strings"
...
@@ -37,6 +36,7 @@ type Config struct {
...
@@ -37,6 +36,7 @@ type Config struct {
SkipCleanNode
bool
`mapstructure:"skip_clean_node"`
SkipCleanNode
bool
`mapstructure:"skip_clean_node"`
SkipInstall
bool
`mapstructure:"skip_install"`
SkipInstall
bool
`mapstructure:"skip_install"`
StagingDir
string
`mapstructure:"staging_directory"`
StagingDir
string
`mapstructure:"staging_directory"`
ClientKey
string
`mapstructure:"client_key"`
ValidationKeyPath
string
`mapstructure:"validation_key_path"`
ValidationKeyPath
string
`mapstructure:"validation_key_path"`
ValidationClientName
string
`mapstructure:"validation_client_name"`
ValidationClientName
string
`mapstructure:"validation_client_name"`
...
@@ -50,6 +50,7 @@ type Provisioner struct {
...
@@ -50,6 +50,7 @@ type Provisioner struct {
type
ConfigTemplate
struct
{
type
ConfigTemplate
struct
{
NodeName
string
NodeName
string
ServerUrl
string
ServerUrl
string
ClientKey
string
ValidationKeyPath
string
ValidationKeyPath
string
ValidationClientName
string
ValidationClientName
string
ChefEnvironment
string
ChefEnvironment
string
...
@@ -162,6 +163,10 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
...
@@ -162,6 +163,10 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
return
fmt
.
Errorf
(
"Error creating staging directory: %s"
,
err
)
return
fmt
.
Errorf
(
"Error creating staging directory: %s"
,
err
)
}
}
if
p
.
config
.
ClientKey
==
""
{
p
.
config
.
ClientKey
=
fmt
.
Sprintf
(
"%s/client.pem"
,
p
.
config
.
StagingDir
)
}
if
p
.
config
.
ValidationKeyPath
!=
""
{
if
p
.
config
.
ValidationKeyPath
!=
""
{
remoteValidationKeyPath
=
fmt
.
Sprintf
(
"%s/validation.pem"
,
p
.
config
.
StagingDir
)
remoteValidationKeyPath
=
fmt
.
Sprintf
(
"%s/validation.pem"
,
p
.
config
.
StagingDir
)
if
err
:=
p
.
copyValidationKey
(
ui
,
comm
,
remoteValidationKeyPath
);
err
!=
nil
{
if
err
:=
p
.
copyValidationKey
(
ui
,
comm
,
remoteValidationKeyPath
);
err
!=
nil
{
...
@@ -170,7 +175,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
...
@@ -170,7 +175,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
}
}
configPath
,
err
:=
p
.
createConfig
(
configPath
,
err
:=
p
.
createConfig
(
ui
,
comm
,
nodeName
,
serverUrl
,
remoteValidationKeyPath
,
p
.
config
.
ValidationClientName
,
p
.
config
.
ChefEnvironment
,
p
.
config
.
SslVerifyMode
)
ui
,
comm
,
nodeName
,
serverUrl
,
p
.
config
.
ClientKey
,
remoteValidationKeyPath
,
p
.
config
.
ValidationClientName
,
p
.
config
.
ChefEnvironment
,
p
.
config
.
SslVerifyMode
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"Error creating Chef config file: %s"
,
err
)
return
fmt
.
Errorf
(
"Error creating Chef config file: %s"
,
err
)
}
}
...
@@ -224,7 +229,7 @@ func (p *Provisioner) uploadDirectory(ui packer.Ui, comm packer.Communicator, ds
...
@@ -224,7 +229,7 @@ func (p *Provisioner) uploadDirectory(ui packer.Ui, comm packer.Communicator, ds
return
comm
.
UploadDir
(
dst
,
src
,
nil
)
return
comm
.
UploadDir
(
dst
,
src
,
nil
)
}
}
func
(
p
*
Provisioner
)
createConfig
(
ui
packer
.
Ui
,
comm
packer
.
Communicator
,
nodeName
string
,
serverUrl
string
,
remoteKeyPath
string
,
validationClientName
string
,
chefEnvironment
string
,
sslVerifyMode
string
)
(
string
,
error
)
{
func
(
p
*
Provisioner
)
createConfig
(
ui
packer
.
Ui
,
comm
packer
.
Communicator
,
nodeName
string
,
serverUrl
string
,
clientKey
string
,
remoteKeyPath
string
,
validationClientName
string
,
chefEnvironment
string
,
sslVerifyMode
string
)
(
string
,
error
)
{
ui
.
Message
(
"Creating configuration file 'client.rb'"
)
ui
.
Message
(
"Creating configuration file 'client.rb'"
)
// Read the template
// Read the template
...
@@ -248,6 +253,7 @@ func (p *Provisioner) createConfig(ui packer.Ui, comm packer.Communicator, nodeN
...
@@ -248,6 +253,7 @@ func (p *Provisioner) createConfig(ui packer.Ui, comm packer.Communicator, nodeN
ctx
.
Data
=
&
ConfigTemplate
{
ctx
.
Data
=
&
ConfigTemplate
{
NodeName
:
nodeName
,
NodeName
:
nodeName
,
ServerUrl
:
serverUrl
,
ServerUrl
:
serverUrl
,
ClientKey
:
clientKey
,
ValidationKeyPath
:
remoteKeyPath
,
ValidationKeyPath
:
remoteKeyPath
,
ValidationClientName
:
validationClientName
,
ValidationClientName
:
validationClientName
,
ChefEnvironment
:
chefEnvironment
,
ChefEnvironment
:
chefEnvironment
,
...
@@ -303,16 +309,25 @@ func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir stri
...
@@ -303,16 +309,25 @@ func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir stri
mkdirCmd
=
"sudo "
+
mkdirCmd
mkdirCmd
=
"sudo "
+
mkdirCmd
}
}
cmd
:=
&
packer
.
RemoteCmd
{
cmd
:=
&
packer
.
RemoteCmd
{
Command
:
mkdirCmd
}
Command
:
mkdirCmd
,
if
err
:=
cmd
.
StartWithUi
(
comm
,
ui
);
err
!=
nil
{
return
err
}
if
cmd
.
ExitStatus
!=
0
{
return
fmt
.
Errorf
(
"Non-zero exit status. See output above for more info."
)
}
}
// Chmod the directory to 0777 just so that we can access it as our user
mkdirCmd
=
fmt
.
Sprintf
(
"chmod 0777 '%s'"
,
dir
)
if
!
p
.
config
.
PreventSudo
{
mkdirCmd
=
"sudo "
+
mkdirCmd
}
cmd
=
&
packer
.
RemoteCmd
{
Command
:
mkdirCmd
}
if
err
:=
cmd
.
StartWithUi
(
comm
,
ui
);
err
!=
nil
{
if
err
:=
cmd
.
StartWithUi
(
comm
,
ui
);
err
!=
nil
{
return
err
return
err
}
}
if
cmd
.
ExitStatus
!=
0
{
if
cmd
.
ExitStatus
!=
0
{
return
fmt
.
Errorf
(
"Non-zero exit status."
)
return
fmt
.
Errorf
(
"Non-zero exit status.
See output above for more info.
"
)
}
}
return
nil
return
nil
...
@@ -320,15 +335,9 @@ func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir stri
...
@@ -320,15 +335,9 @@ func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir stri
func
(
p
*
Provisioner
)
cleanNode
(
ui
packer
.
Ui
,
comm
packer
.
Communicator
,
node
string
)
error
{
func
(
p
*
Provisioner
)
cleanNode
(
ui
packer
.
Ui
,
comm
packer
.
Communicator
,
node
string
)
error
{
ui
.
Say
(
"Cleaning up chef node..."
)
ui
.
Say
(
"Cleaning up chef node..."
)
app
:=
fmt
.
Sprintf
(
"knife node delete %s -y"
,
node
)
args
:=
[]
string
{
"node"
,
"delete"
,
node
}
if
err
:=
p
.
knifeExec
(
ui
,
comm
,
node
,
args
);
err
!=
nil
{
cmd
:=
exec
.
Command
(
"sh"
,
"-c"
,
app
)
return
fmt
.
Errorf
(
"Failed to cleanup node: %s"
,
err
)
out
,
err
:=
cmd
.
Output
()
ui
.
Message
(
fmt
.
Sprintf
(
"%s"
,
out
))
if
err
!=
nil
{
return
err
}
}
return
nil
return
nil
...
@@ -336,16 +345,38 @@ func (p *Provisioner) cleanNode(ui packer.Ui, comm packer.Communicator, node str
...
@@ -336,16 +345,38 @@ func (p *Provisioner) cleanNode(ui packer.Ui, comm packer.Communicator, node str
func
(
p
*
Provisioner
)
cleanClient
(
ui
packer
.
Ui
,
comm
packer
.
Communicator
,
node
string
)
error
{
func
(
p
*
Provisioner
)
cleanClient
(
ui
packer
.
Ui
,
comm
packer
.
Communicator
,
node
string
)
error
{
ui
.
Say
(
"Cleaning up chef client..."
)
ui
.
Say
(
"Cleaning up chef client..."
)
app
:=
fmt
.
Sprintf
(
"knife client delete %s -y"
,
node
)
args
:=
[]
string
{
"client"
,
"delete"
,
node
}
if
err
:=
p
.
knifeExec
(
ui
,
comm
,
node
,
args
);
err
!=
nil
{
return
fmt
.
Errorf
(
"Failed to cleanup client: %s"
,
err
)
}
cmd
:=
exec
.
Command
(
"sh"
,
"-c"
,
app
)
return
nil
out
,
err
:=
cmd
.
Output
()
}
ui
.
Message
(
fmt
.
Sprintf
(
"%s"
,
out
))
func
(
p
*
Provisioner
)
knifeExec
(
ui
packer
.
Ui
,
comm
packer
.
Communicator
,
node
string
,
args
[]
string
)
error
{
flags
:=
[]
string
{
"-y"
,
"-s"
,
fmt
.
Sprintf
(
"'%s'"
,
p
.
config
.
ServerUrl
),
"-k"
,
fmt
.
Sprintf
(
"'%s'"
,
p
.
config
.
ClientKey
),
"-u"
,
fmt
.
Sprintf
(
"'%s'"
,
node
),
}
if
err
!=
nil
{
cmdText
:=
fmt
.
Sprintf
(
"knife %s %s"
,
strings
.
Join
(
args
,
" "
),
strings
.
Join
(
flags
,
" "
))
if
!
p
.
config
.
PreventSudo
{
cmdText
=
"sudo "
+
cmdText
}
cmd
:=
&
packer
.
RemoteCmd
{
Command
:
cmdText
}
if
err
:=
cmd
.
StartWithUi
(
comm
,
ui
);
err
!=
nil
{
return
err
return
err
}
}
if
cmd
.
ExitStatus
!=
0
{
return
fmt
.
Errorf
(
"Non-zero exit status. See output above for more info.
\n\n
"
+
"Command: %s"
,
cmdText
)
}
return
nil
return
nil
}
}
...
@@ -524,6 +555,7 @@ var DefaultConfigTemplate = `
...
@@ -524,6 +555,7 @@ var DefaultConfigTemplate = `
log_level :info
log_level :info
log_location STDOUT
log_location STDOUT
chef_server_url "{{.ServerUrl}}"
chef_server_url "{{.ServerUrl}}"
client_key "{{.ClientKey}}"
{{if ne .ValidationClientName ""}}
{{if ne .ValidationClientName ""}}
validation_client_name "{{.ValidationClientName}}"
validation_client_name "{{.ValidationClientName}}"
{{else}}
{{else}}
...
...
provisioner/file/provisioner.go
View file @
f2f8ad16
...
@@ -20,6 +20,9 @@ type Config struct {
...
@@ -20,6 +20,9 @@ type Config struct {
// The remote path where the local file will be uploaded to.
// The remote path where the local file will be uploaded to.
Destination
string
Destination
string
// Direction
Direction
string
ctx
interpolate
.
Context
ctx
interpolate
.
Context
}
}
...
@@ -38,12 +41,28 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
...
@@ -38,12 +41,28 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
return
err
return
err
}
}
if
p
.
config
.
Direction
==
""
{
p
.
config
.
Direction
=
"upload"
}
var
errs
*
packer
.
MultiError
var
errs
*
packer
.
MultiError
if
_
,
err
:=
os
.
Stat
(
p
.
config
.
Source
);
err
!=
nil
{
if
_
,
err
:=
os
.
Stat
(
p
.
config
.
Source
);
err
!=
nil
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
errs
=
packer
.
MultiErrorAppend
(
errs
,
fmt
.
Errorf
(
"Bad source '%s': %s"
,
p
.
config
.
Source
,
err
))
fmt
.
Errorf
(
"Bad source '%s': %s"
,
p
.
config
.
Source
,
err
))
}
}
if
p
.
config
.
Direction
!=
"download"
&&
p
.
config
.
Direction
!=
"upload"
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
errors
.
New
(
"Direction must be one of: download, upload."
))
}
if
p
.
config
.
Direction
==
"upload"
{
if
_
,
err
:=
os
.
Stat
(
p
.
config
.
Source
);
err
!=
nil
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
fmt
.
Errorf
(
"Bad source '%s': %s"
,
p
.
config
.
Source
,
err
))
}
}
if
p
.
config
.
Destination
==
""
{
if
p
.
config
.
Destination
==
""
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
errs
=
packer
.
MultiErrorAppend
(
errs
,
errors
.
New
(
"Destination must be specified."
))
errors
.
New
(
"Destination must be specified."
))
...
@@ -57,6 +76,30 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
...
@@ -57,6 +76,30 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
}
}
func
(
p
*
Provisioner
)
Provision
(
ui
packer
.
Ui
,
comm
packer
.
Communicator
)
error
{
func
(
p
*
Provisioner
)
Provision
(
ui
packer
.
Ui
,
comm
packer
.
Communicator
)
error
{
if
p
.
config
.
Direction
==
"download"
{
return
p
.
ProvisionDownload
(
ui
,
comm
)
}
else
{
return
p
.
ProvisionUpload
(
ui
,
comm
)
}
}
func
(
p
*
Provisioner
)
ProvisionDownload
(
ui
packer
.
Ui
,
comm
packer
.
Communicator
)
error
{
ui
.
Say
(
fmt
.
Sprintf
(
"Downloading %s => %s"
,
p
.
config
.
Source
,
p
.
config
.
Destination
))
f
,
err
:=
os
.
OpenFile
(
p
.
config
.
Destination
,
os
.
O_CREATE
|
os
.
O_WRONLY
|
os
.
O_TRUNC
,
0644
)
if
err
!=
nil
{
return
err
}
defer
f
.
Close
()
err
=
comm
.
Download
(
p
.
config
.
Source
,
f
)
if
err
!=
nil
{
ui
.
Error
(
fmt
.
Sprintf
(
"Download failed: %s"
,
err
))
}
return
err
}
func
(
p
*
Provisioner
)
ProvisionUpload
(
ui
packer
.
Ui
,
comm
packer
.
Communicator
)
error
{
ui
.
Say
(
fmt
.
Sprintf
(
"Uploading %s => %s"
,
p
.
config
.
Source
,
p
.
config
.
Destination
))
ui
.
Say
(
fmt
.
Sprintf
(
"Uploading %s => %s"
,
p
.
config
.
Source
,
p
.
config
.
Destination
))
info
,
err
:=
os
.
Stat
(
p
.
config
.
Source
)
info
,
err
:=
os
.
Stat
(
p
.
config
.
Source
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
provisioner/puppet-masterless/provisioner.go
View file @
f2f8ad16
...
@@ -44,6 +44,10 @@ type Config struct {
...
@@ -44,6 +44,10 @@ type Config struct {
// The directory where files will be uploaded. Packer requires write
// The directory where files will be uploaded. Packer requires write
// permissions in this directory.
// permissions in this directory.
StagingDir
string
`mapstructure:"staging_directory"`
StagingDir
string
`mapstructure:"staging_directory"`
// The directory from which the command will be executed.
// Packer requires the directory to exist when running puppet.
WorkingDir
string
`mapstructure:"working_directory"`
}
}
type
Provisioner
struct
{
type
Provisioner
struct
{
...
@@ -51,6 +55,7 @@ type Provisioner struct {
...
@@ -51,6 +55,7 @@ type Provisioner struct {
}
}
type
ExecuteTemplate
struct
{
type
ExecuteTemplate
struct
{
WorkingDir
string
FacterVars
string
FacterVars
string
HieraConfigPath
string
HieraConfigPath
string
ModulePath
string
ModulePath
string
...
@@ -74,7 +79,8 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
...
@@ -74,7 +79,8 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
// Set some defaults
// Set some defaults
if
p
.
config
.
ExecuteCommand
==
""
{
if
p
.
config
.
ExecuteCommand
==
""
{
p
.
config
.
ExecuteCommand
=
"{{.FacterVars}} {{if .Sudo}} sudo -E {{end}}"
+
p
.
config
.
ExecuteCommand
=
"cd {{.WorkingDir}} && "
+
"{{.FacterVars}} {{if .Sudo}} sudo -E {{end}}"
+
"puppet apply --verbose --modulepath='{{.ModulePath}}' "
+
"puppet apply --verbose --modulepath='{{.ModulePath}}' "
+
"{{if ne .HieraConfigPath
\"\"
}}--hiera_config='{{.HieraConfigPath}}' {{end}}"
+
"{{if ne .HieraConfigPath
\"\"
}}--hiera_config='{{.HieraConfigPath}}' {{end}}"
+
"{{if ne .ManifestDir
\"\"
}}--manifestdir='{{.ManifestDir}}' {{end}}"
+
"{{if ne .ManifestDir
\"\"
}}--manifestdir='{{.ManifestDir}}' {{end}}"
+
...
@@ -86,6 +92,16 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
...
@@ -86,6 +92,16 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
p
.
config
.
StagingDir
=
"/tmp/packer-puppet-masterless"
p
.
config
.
StagingDir
=
"/tmp/packer-puppet-masterless"
}
}
if
p
.
config
.
WorkingDir
==
""
{
p
.
config
.
WorkingDir
=
p
.
config
.
StagingDir
}
if
p
.
config
.
Facter
==
nil
{
p
.
config
.
Facter
=
make
(
map
[
string
]
string
)
}
p
.
config
.
Facter
[
"packer_build_name"
]
=
p
.
config
.
PackerBuildName
p
.
config
.
Facter
[
"packer_builder_type"
]
=
p
.
config
.
PackerBuilderType
// Validation
// Validation
var
errs
*
packer
.
MultiError
var
errs
*
packer
.
MultiError
if
p
.
config
.
HieraConfigPath
!=
""
{
if
p
.
config
.
HieraConfigPath
!=
""
{
...
@@ -200,6 +216,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
...
@@ -200,6 +216,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
ManifestFile
:
remoteManifestFile
,
ManifestFile
:
remoteManifestFile
,
ModulePath
:
strings
.
Join
(
modulePaths
,
":"
),
ModulePath
:
strings
.
Join
(
modulePaths
,
":"
),
Sudo
:
!
p
.
config
.
PreventSudo
,
Sudo
:
!
p
.
config
.
PreventSudo
,
WorkingDir
:
p
.
config
.
WorkingDir
,
}
}
command
,
err
:=
interpolate
.
Render
(
p
.
config
.
ExecuteCommand
,
&
p
.
config
.
ctx
)
command
,
err
:=
interpolate
.
Render
(
p
.
config
.
ExecuteCommand
,
&
p
.
config
.
ctx
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
provisioner/puppet-masterless/provisioner_test.go
View file @
f2f8ad16
...
@@ -133,3 +133,47 @@ func TestProvisionerPrepare_modulePaths(t *testing.T) {
...
@@ -133,3 +133,47 @@ func TestProvisionerPrepare_modulePaths(t *testing.T) {
t
.
Fatalf
(
"err: %s"
,
err
)
t
.
Fatalf
(
"err: %s"
,
err
)
}
}
}
}
func
TestProvisionerPrepare_facterFacts
(
t
*
testing
.
T
)
{
config
:=
testConfig
()
delete
(
config
,
"facter"
)
p
:=
new
(
Provisioner
)
err
:=
p
.
Prepare
(
config
)
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
// Test with malformed fact
config
[
"facter"
]
=
"fact=stringified"
p
=
new
(
Provisioner
)
err
=
p
.
Prepare
(
config
)
if
err
==
nil
{
t
.
Fatal
(
"should be an error"
)
}
// Test with a good one
td
,
err
:=
ioutil
.
TempDir
(
""
,
"packer"
)
if
err
!=
nil
{
t
.
Fatalf
(
"error: %s"
,
err
)
}
defer
os
.
RemoveAll
(
td
)
facts
:=
make
(
map
[
string
]
string
)
facts
[
"fact_name"
]
=
"fact_value"
config
[
"facter"
]
=
facts
p
=
new
(
Provisioner
)
err
=
p
.
Prepare
(
config
)
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
// Make sure the default facts are present
delete
(
config
,
"facter"
)
p
=
new
(
Provisioner
)
err
=
p
.
Prepare
(
config
)
if
p
.
config
.
Facter
==
nil
{
t
.
Fatalf
(
"err: Default facts are not set in the Puppet provisioner!"
)
}
}
provisioner/shell/provisioner.go
View file @
f2f8ad16
...
@@ -266,12 +266,25 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
...
@@ -266,12 +266,25 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
return
err
return
err
}
}
// Close the original file since we copied it
f
.
Close
()
if
cmd
.
ExitStatus
!=
0
{
if
cmd
.
ExitStatus
!=
0
{
return
fmt
.
Errorf
(
"Script exited with non-zero exit status: %d"
,
cmd
.
ExitStatus
)
return
fmt
.
Errorf
(
"Script exited with non-zero exit status: %d"
,
cmd
.
ExitStatus
)
}
}
// Delete the temporary file we created
cmd
=
&
packer
.
RemoteCmd
{
Command
:
fmt
.
Sprintf
(
"rm -f %s"
,
p
.
config
.
RemotePath
),
}
if
err
:=
comm
.
Start
(
cmd
);
err
!=
nil
{
return
fmt
.
Errorf
(
"Error removing temporary script at %s: %s"
,
p
.
config
.
RemotePath
,
err
)
}
cmd
.
Wait
()
if
cmd
.
ExitStatus
!=
0
{
return
fmt
.
Errorf
(
"Error removing temporary script at %s!"
,
p
.
config
.
RemotePath
)
}
}
}
return
nil
return
nil
...
...
website/source/docs/builders/amazon-ebs.html.markdown
View file @
f2f8ad16
...
@@ -62,10 +62,25 @@ each category, the available configuration keys are alphabetized.
...
@@ -62,10 +62,25 @@ each category, the available configuration keys are alphabetized.
*
`ami_block_device_mappings`
(array of block device mappings) - Add the block
*
`ami_block_device_mappings`
(array of block device mappings) - Add the block
device mappings to the AMI. The block device mappings allow for keys:
device mappings to the AMI. The block device mappings allow for keys:
"device
\_
name" (string), "virtual
\_
name" (string), "snapshot
\_
id" (string),
"volume
\_
type" (string), "volume
\_
size" (integer), "delete
\_
on
\_
termination"
-
`device_name`
(string) – The device name exposed to the instance (for
(boolean), "encrypted" (boolean), "no
\_
device" (boolean), and "iops"
example, "/dev/sdh" or "xvdh")
(integer).
-
`virtual_name`
(string) – The virtual device name. See the documentation on
[
Block Device Mapping
][
1
]
for more information
-
`snapshot_id`
(string) – The ID of the snapshot
-
`volume_type`
(string) – The volume type. gp2 for General Purpose (SSD)
volumes, io1 for Provisioned IOPS (SSD) volumes, and standard for Magnetic
volumes
-
`volume_size`
(integer) – The size of the volume, in GiB. Required if not
specifying a
`snapshot_id`
-
`delete_on_termination`
(boolean) – Indicates whether the EBS volume is
deleted on instance termination
-
`encrypted`
(boolean) – Indicates whether to encrypt the volume or not
-
`no_device`
(boolean) – Suppresses the specified device included in the
block device mapping of the AMI
-
`iops`
(integer) – The number of I/O operations per second (IOPS) that the
volume supports. See the documentation on
[
IOPs
][
2
]
for more information
*
`ami_description`
(string) - The description to set for the resulting
*
`ami_description`
(string) - The description to set for the resulting
AMI(s). By default this description is empty.
AMI(s). By default this description is empty.
...
@@ -133,11 +148,17 @@ AMI if one with the same name already exists. Default `false`.
...
@@ -133,11 +148,17 @@ AMI if one with the same name already exists. Default `false`.
spot price. This must be one of:
`Linux/UNIX`
,
`SUSE Linux`
,
`Windows`
,
spot price. This must be one of:
`Linux/UNIX`
,
`SUSE Linux`
,
`Windows`
,
`Linux/UNIX (Amazon VPC)`
,
`SUSE Linux (Amazon VPC)`
,
`Windows (Amazon VPC)`
`Linux/UNIX (Amazon VPC)`
,
`SUSE Linux (Amazon VPC)`
,
`Windows (Amazon VPC)`
*
`ssh_keypair_name`
(string) - If specified, this is the key that will be
used for SSH with the machine. By default, this is blank, and Packer will
generate a temporary keypair.
`ssh_private_key_file`
must be specified
with this.
*
`ssh_port`
(integer) - The port that SSH will be available on. This defaults
*
`ssh_port`
(integer) - The port that SSH will be available on. This defaults
to port 22.
to port 22.
*
`ssh_private_key_file`
(string) - Use this ssh private key file instead of
*
`ssh_private_key_file`
(string) - Use this ssh private key file instead of
a generated ssh key pair for connecting to the instance.
a generated ssh key pair for connecting to the instance. This key file must
already exist on the
`source_ami`
*
`ssh_private_ip`
(bool) - If true, then SSH will always use the private
*
`ssh_private_ip`
(bool) - If true, then SSH will always use the private
IP if available.
IP if available.
...
@@ -255,3 +276,7 @@ Here is an example using the optional AMI tags. This will add the tags
...
@@ -255,3 +276,7 @@ Here is an example using the optional AMI tags. This will add the tags
}
}
}
}
```
```
[
1
]:
http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_BlockDeviceMapping.html
[
2
]:
http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html
website/source/docs/builders/amazon-instance.html.markdown
View file @
f2f8ad16
...
@@ -82,10 +82,24 @@ each category, the available configuration keys are alphabetized.
...
@@ -82,10 +82,24 @@ each category, the available configuration keys are alphabetized.
*
`ami_block_device_mappings`
(array of block device mappings) - Add the block
*
`ami_block_device_mappings`
(array of block device mappings) - Add the block
device mappings to the AMI. The block device mappings allow for keys:
device mappings to the AMI. The block device mappings allow for keys:
"device
\_
name" (string), "virtual
\_
name" (string), "snapshot
\_
id" (string),
"volume
\_
type" (string), "volume
\_
size" (integer), "delete
\_
on
\_
termination"
-
`device_name`
(string) – The device name exposed to the instance (for
(boolean), "encrypted" (boolean), "no
\_
device" (boolean), and "iops" (integer).
example, "/dev/sdh" or "xvdh")
See
[
amazon-ebs
](
/docs/builders/amazon-ebs.html
)
for an example template.
-
`virtual_name`
(string) – The virtual device name. See the documentation on
[
Block Device Mapping
][
1
]
for more information
-
`snapshot_id`
(string) – The ID of the snapshot
-
`volume_type`
(string) – The volume type. gp2 for General Purpose (SSD)
volumes, io1 for Provisioned IOPS (SSD) volumes, and standard for Magnetic
volumes
-
`volume_size`
(integer) – The size of the volume, in GiB. Required if not
specifying a
`snapshot_id`
-
`delete_on_termination`
(boolean) – Indicates whether the EBS volume is
deleted on instance termination
-
`encrypted`
(boolean) – Indicates whether to encrypt the volume or not
-
`no_device`
(boolean) – Suppresses the specified device included in the
block device mapping of the AMI
-
`iops`
(integer) – The number of I/O operations per second (IOPS) that the
volume supports. See the documentation on
[
IOPs
][
2
]
for more information
*
`ami_description`
(string) - The description to set for the resulting
*
`ami_description`
(string) - The description to set for the resulting
AMI(s). By default this description is empty.
AMI(s). By default this description is empty.
...
@@ -173,11 +187,17 @@ AMI if one with the same name already exists. Default `false`.
...
@@ -173,11 +187,17 @@ AMI if one with the same name already exists. Default `false`.
spot price. This must be one of:
`Linux/UNIX`
,
`SUSE Linux`
,
`Windows`
,
spot price. This must be one of:
`Linux/UNIX`
,
`SUSE Linux`
,
`Windows`
,
`Linux/UNIX (Amazon VPC)`
,
`SUSE Linux (Amazon VPC)`
,
`Windows (Amazon VPC)`
`Linux/UNIX (Amazon VPC)`
,
`SUSE Linux (Amazon VPC)`
,
`Windows (Amazon VPC)`
*
`ssh_keypair_name`
(string) - If specified, this is the key that will be
used for SSH with the machine. By default, this is blank, and Packer will
generate a temporary keypair.
`ssh_private_key_file`
must be specified
with this.
*
`ssh_port`
(integer) - The port that SSH will be available on. This defaults
*
`ssh_port`
(integer) - The port that SSH will be available on. This defaults
to port 22.
to port 22.
*
`ssh_private_key_file`
(string) - Use this ssh private key file instead of
*
`ssh_private_key_file`
(string) - Use this ssh private key file instead of
a generated ssh key pair for connecting to the instance.
a generated ssh key pair for connecting to the instance. This key file must
already exist on the
`source_ami`
*
`ssh_private_ip`
(bool) - If true, then SSH will always use the private
*
`ssh_private_ip`
(bool) - If true, then SSH will always use the private
IP if available.
IP if available.
...
@@ -318,3 +338,6 @@ sudo -i -n ec2-upload-bundle \
...
@@ -318,3 +338,6 @@ sudo -i -n ec2-upload-bundle \
The available template variables should be self-explanatory based on the
The available template variables should be self-explanatory based on the
parameters they're used to satisfy the
`ec2-upload-bundle`
command.
parameters they're used to satisfy the
`ec2-upload-bundle`
command.
[
1
]:
http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_BlockDeviceMapping.html
[
2
]:
http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html
website/source/docs/builders/parallels-iso.html.markdown
View file @
f2f8ad16
...
@@ -32,7 +32,7 @@ Ubuntu to self-install. Still, the example serves to show the basic configuratio
...
@@ -32,7 +32,7 @@ Ubuntu to self-install. Still, the example serves to show the basic configuratio
"
iso_url
"
:
"
http://releases.ubuntu.com/12.04/ubuntu-12.04.3-server-amd64.iso
"
,
"
iso_url
"
:
"
http://releases.ubuntu.com/12.04/ubuntu-12.04.3-server-amd64.iso
"
,
"
iso_checksum
"
:
"
2cbe868812a871242cdcdd8f2fd6feb9
"
,
"
iso_checksum
"
:
"
2cbe868812a871242cdcdd8f2fd6feb9
"
,
"
iso_checksum_type
"
:
"
md5
"
,
"
iso_checksum_type
"
:
"
md5
"
,
"
parallels_tools_flavor
"
:
"
lin
"
"
parallels_tools_flavor
"
:
"
lin
"
,
"
ssh_username
"
:
"
packer
"
,
"
ssh_username
"
:
"
packer
"
,
"
ssh_password
"
:
"
packer
"
,
"
ssh_password
"
:
"
packer
"
,
"
ssh_wait_timeout
"
:
"
30s
"
,
"
ssh_wait_timeout
"
:
"
30s
"
,
...
...
website/source/docs/provisioners/chef-client.html.markdown
View file @
f2f8ad16
...
@@ -88,6 +88,9 @@ configuration is actually required.
...
@@ -88,6 +88,9 @@ configuration is actually required.
this folder. If the permissions are not correct, use a shell provisioner
this folder. If the permissions are not correct, use a shell provisioner
prior to this to configure it properly.
prior to this to configure it properly.
*
`client_key`
(string) - Path to client key. If not set, this defaults to a file
named client.pem in
`staging_directory`
.
*
`validation_client_name`
(string) - Name of the validation client. If
*
`validation_client_name`
(string) - Name of the validation client. If
not set, this won't be set in the configuration and the default that Chef
not set, this won't be set in the configuration and the default that Chef
uses will be used.
uses will be used.
...
@@ -158,3 +161,12 @@ curl -L https://www.opscode.com/chef/install.sh | \
...
@@ -158,3 +161,12 @@ curl -L https://www.opscode.com/chef/install.sh | \
```
```
This command can be customized using the
`install_command`
configuration.
This command can be customized using the
`install_command`
configuration.
## Folder Permissions
!> The
`chef-client`
provisioner will chmod the directory with your Chef
keys to 777. This is to ensure that Packer can upload and make use of that
directory. However, once the machine is created, you usually don't
want to keep these directories with those permissions. To change the
permissions on the directories, append a shell provisioner after Chef
to modify them.
website/source/docs/provisioners/file.html.markdown
View file @
f2f8ad16
...
@@ -40,6 +40,10 @@ The available configuration options are listed below. All elements are required.
...
@@ -40,6 +40,10 @@ The available configuration options are listed below. All elements are required.
machine. This value must be a writable location and any parent directories
machine. This value must be a writable location and any parent directories
must already exist.
must already exist.
*
`direction`
(string) - The direction of the file transfer. This defaults
to "upload." If it is set to "download" then the file "source" in
the machine wll be downloaded locally to "destination"
## Directory Uploads
## Directory Uploads
The file provisioner is also able to upload a complete directory to the
The file provisioner is also able to upload a complete directory to the
...
...
website/source/docs/provisioners/puppet-masterless.html.markdown
View file @
f2f8ad16
...
@@ -79,12 +79,18 @@ Optional parameters:
...
@@ -79,12 +79,18 @@ Optional parameters:
this folder. If the permissions are not correct, use a shell provisioner
this folder. If the permissions are not correct, use a shell provisioner
prior to this to configure it properly.
prior to this to configure it properly.
*
`working_directory`
(string) - This is the directory from which the puppet command
will be run. When using hiera with a relative path, this option allows to ensure
that the paths are working properly. If not specified, defaults to the value of
specified
`staging_directory`
(or its default value if not specified either).
## Execute Command
## Execute Command
By default, Packer uses the following command (broken across multiple lines
By default, Packer uses the following command (broken across multiple lines
for readability) to execute Puppet:
for readability) to execute Puppet:
```
liquid
```
liquid
cd
{{.
WorkingDir
}}
&& \
{{.
FacterVars
}}{{
if
.
Sudo
}}
sudo -E
{{
end
}}
puppet apply \
{{.
FacterVars
}}{{
if
.
Sudo
}}
sudo -E
{{
end
}}
puppet apply \
--verbose \
--verbose \
--modulepath='
{{.
ModulePath
}}
' \
--modulepath='
{{.
ModulePath
}}
' \
...
@@ -98,6 +104,7 @@ This command can be customized using the `execute_command` configuration.
...
@@ -98,6 +104,7 @@ This command can be customized using the `execute_command` configuration.
As you can see from the default value above, the value of this configuration
As you can see from the default value above, the value of this configuration
can contain various template variables, defined below:
can contain various template variables, defined below:
*
`WorkingDir`
- The path from which Puppet will be executed.
*
`FacterVars`
- Shell-friendly string of environmental variables used
*
`FacterVars`
- Shell-friendly string of environmental variables used
to set custom facts configured for this provisioner.
to set custom facts configured for this provisioner.
*
`HieraConfigPath`
- The path to a hiera configuration file.
*
`HieraConfigPath`
- The path to a hiera configuration file.
...
@@ -106,3 +113,17 @@ can contain various template variables, defined below:
...
@@ -106,3 +113,17 @@ can contain various template variables, defined below:
*
`ModulePath`
- The paths to the module directories.
*
`ModulePath`
- The paths to the module directories.
*
`Sudo`
- A boolean of whether to
`sudo`
the command or not, depending on
*
`Sudo`
- A boolean of whether to
`sudo`
the command or not, depending on
the value of the
`prevent_sudo`
configuration.
the value of the
`prevent_sudo`
configuration.
## Default Facts
In addition to being able to specify custom Facter facts using the
`facter`
configuration, the provisioner automatically defines certain commonly useful
facts:
*
`packer_build_name`
is set to the name of the build that Packer is running.
This is most useful when Packer is making multiple builds and you want to
distinguish them in your Hiera hierarchy.
*
`packer_builder_type`
is the type of the builder that was used to create the
machine that Puppet is running on. This is useful if you want to run only
certain parts of your Puppet code on systems built with certain builders.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment