@ -95,6 +95,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
sliceTemplates := map [ string ] [ ] string {
"cookbook_paths" : p . config . CookbookPaths ,
"remote_cookbook_paths" : p . config . RemoteCookbookPaths ,
"run_list" : p . config . RunList ,
}
for n , slice := range sliceTemplates {
@ -129,6 +130,14 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
}
}
// Process the user variables within the JSON and set the JSON.
// Do this early so that we can validate and show errors.
p . config . Json , err = p . processJsonUserVars ( )
if err != nil {
errs = packer . MultiErrorAppend (
errs , fmt . Errorf ( "Error processing user variables in JSON: %s" , err ) )
}
if errs != nil && len ( errs . Errors ) > 0 {
return errs
}
@ -136,6 +145,46 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
return nil
}
func ( p * Provisioner ) processJsonUserVars ( ) ( map [ string ] interface { } , error ) {
jsonBytes , err := json . Marshal ( p . config . Json )
if err != nil {
// This really shouldn't happen since we literally just unmarshalled
panic ( err )
}
// Copy the user variables so that we can restore them later, and
// make sure we make the quotes JSON-friendly in the user variables.
originalUserVars := make ( map [ string ] string )
for k , v := range p . config . tpl . UserVars {
originalUserVars [ k ] = v
}
// Make sure we reset them no matter what
defer func ( ) {
p . config . tpl . UserVars = originalUserVars
} ( )
// Make the current user variables JSON string safe.
for k , v := range p . config . tpl . UserVars {
v = strings . Replace ( v , ` \ ` , ` \\ ` , - 1 )
v = strings . Replace ( v , ` " ` , ` \" ` , - 1 )
p . config . tpl . UserVars [ k ] = v
}
// Process the bytes with the template processor
jsonBytesProcessed , err := p . config . tpl . Process ( string ( jsonBytes ) , nil )
if err != nil {
return nil , err
}
var result map [ string ] interface { }
if err := json . Unmarshal ( [ ] byte ( jsonBytesProcessed ) , & result ) ; err != nil {
return nil , err
}
return result , nil
}
func ( p * Provisioner ) Provision ( ui packer . Ui , comm packer . Communicator ) error {
if ! p . config . SkipInstall {
if err := p . installChef ( ui , comm ) ; err != nil {
@ -236,14 +285,9 @@ func (p *Provisioner) createJson(ui packer.Ui, comm packer.Communicator) (string
return "" , err
}
jsonBytesProcessed , err := p . config . tpl . Process ( string ( jsonBytes ) , nil )
if err != nil {
return "" , err
}
// Upload the bytes
remotePath := filepath . Join ( p . config . StagingDir , "node.json" )
if err := comm . Upload ( remotePath , bytes . NewReader ( [ ] byte ( jsonBytes Processed) ) ) ; err != nil {
if err := comm . Upload ( remotePath , bytes . NewReader ( jsonBytes ) ) ; err != nil {
return "" , err
}