provisioner/chef-solo: deeploy nested JSON works properly
This commit is contained in:
parent
3ac246d611
commit
8fc46aaa82
|
@ -52,6 +52,7 @@ BUG FIXES:
|
||||||
Windows [GH-963]
|
Windows [GH-963]
|
||||||
* provisioner/ansible: set cwd to staging directory [GH-1016]
|
* provisioner/ansible: set cwd to staging directory [GH-1016]
|
||||||
* provisioners/chef-client: Don't chown directory with Ubuntu. [GH-939]
|
* provisioners/chef-client: Don't chown directory with Ubuntu. [GH-939]
|
||||||
|
* provisioners/chef-solo: Deeply nested JSON works properly. [GH-1076]
|
||||||
* provisioners/shell: Env var values can have equal signs. [GH-1045]
|
* provisioners/shell: Env var values can have equal signs. [GH-1045]
|
||||||
* provisioners/shell: chmod the uploaded script file to 0777. [GH-994]
|
* provisioners/shell: chmod the uploaded script file to 0777. [GH-994]
|
||||||
* post-processor/docker-push: Allow repositories with ports. [GH-923]
|
* post-processor/docker-push: Allow repositories with ports. [GH-923]
|
||||||
|
|
|
@ -203,12 +203,24 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the user variables within the JSON and set the JSON.
|
jsonValid := true
|
||||||
// Do this early so that we can validate and show errors.
|
for k, v := range p.config.Json {
|
||||||
p.config.Json, err = p.processJsonUserVars()
|
p.config.Json[k], err = p.deepJsonFix(k, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = packer.MultiErrorAppend(
|
errs = packer.MultiErrorAppend(
|
||||||
errs, fmt.Errorf("Error processing user variables in JSON: %s", err))
|
errs, fmt.Errorf("Error processing JSON: %s", err))
|
||||||
|
jsonValid = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if jsonValid {
|
||||||
|
// 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 {
|
if errs != nil && len(errs.Errors) > 0 {
|
||||||
|
@ -470,6 +482,57 @@ func (p *Provisioner) installChef(ui packer.Ui, comm packer.Communicator) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provisioner) deepJsonFix(key string, current interface{}) (interface{}, error) {
|
||||||
|
if current == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch c := current.(type) {
|
||||||
|
case []interface{}:
|
||||||
|
val := make([]interface{}, len(c))
|
||||||
|
for i, v := range c {
|
||||||
|
var err error
|
||||||
|
val[i], err = p.deepJsonFix(fmt.Sprintf("%s[%d]", key, i), v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return val, nil
|
||||||
|
case bool:
|
||||||
|
return c, nil
|
||||||
|
case int:
|
||||||
|
return c, nil
|
||||||
|
case uint:
|
||||||
|
return c, nil
|
||||||
|
case float32:
|
||||||
|
return c, nil
|
||||||
|
case float64:
|
||||||
|
return c, nil
|
||||||
|
case map[interface{}]interface{}:
|
||||||
|
val := make(map[string]interface{})
|
||||||
|
for k, v := range c {
|
||||||
|
ks, ok := k.(string)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("%s: key is not string", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
val[ks], err = p.deepJsonFix(
|
||||||
|
fmt.Sprintf("%s.%s", key, ks), v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return val, nil
|
||||||
|
case string:
|
||||||
|
return c, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Unknown type for key: '%s'", key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provisioner) processJsonUserVars() (map[string]interface{}, error) {
|
func (p *Provisioner) processJsonUserVars() (map[string]interface{}, error) {
|
||||||
jsonBytes, err := json.Marshal(p.config.Json)
|
jsonBytes, err := json.Marshal(p.config.Json)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -262,3 +262,33 @@ func TestProvisionerPrepare_json(t *testing.T) {
|
||||||
t.Fatalf("bad: %#v", p.config.Json)
|
t.Fatalf("bad: %#v", p.config.Json)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProvisionerPrepare_jsonNested(t *testing.T) {
|
||||||
|
config := testConfig()
|
||||||
|
config["json"] = map[string]interface{}{
|
||||||
|
"foo": map[interface{}]interface{}{
|
||||||
|
"bar": "baz",
|
||||||
|
},
|
||||||
|
|
||||||
|
"bar": []interface{}{
|
||||||
|
"foo",
|
||||||
|
|
||||||
|
map[interface{}]interface{}{
|
||||||
|
"bar": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"bFalse": false,
|
||||||
|
"bTrue": true,
|
||||||
|
"bNil": nil,
|
||||||
|
|
||||||
|
"bInt": 1,
|
||||||
|
"bFloat": 4.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
var p Provisioner
|
||||||
|
err := p.Prepare(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue