chef-solo: json_string to HCL2 templates compatibility (#10655)
This commit is contained in:
parent
95fb13209a
commit
ff5b55b560
|
@ -56,7 +56,12 @@ type Config struct {
|
|||
ExecuteCommand string `mapstructure:"execute_command"`
|
||||
InstallCommand string `mapstructure:"install_command"`
|
||||
RemoteCookbookPaths []string `mapstructure:"remote_cookbook_paths"`
|
||||
Json map[string]interface{}
|
||||
// HCL cannot be decoded into an interface so for HCL templates you must use the JsonString option,
|
||||
// To be used with https://www.packer.io/docs/templates/hcl_templates/functions/encoding/jsonencode
|
||||
// ref: https://github.com/hashicorp/hcl/issues/291#issuecomment-496347585
|
||||
JsonString string `mapstructure:"json_string"`
|
||||
// For JSON templates we keep the map[string]interface{}
|
||||
Json map[string]interface{} `mapstructure:"json" mapstructure-to-hcl2:",skip"`
|
||||
PreventSudo bool `mapstructure:"prevent_sudo"`
|
||||
RunList []string `mapstructure:"run_list"`
|
||||
SkipInstall bool `mapstructure:"skip_install"`
|
||||
|
@ -120,6 +125,12 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if p.config.JsonString != "" {
|
||||
if err := json.Unmarshal([]byte(p.config.JsonString), &p.config.Json); err != nil {
|
||||
return fmt.Errorf("Failed to unmarshal 'json_string': %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if p.config.GuestOSType == "" {
|
||||
p.config.GuestOSType = guestexec.DefaultOSType
|
||||
}
|
||||
|
@ -398,12 +409,10 @@ func (p *Provisioner) createJson(ui packersdk.Ui, comm packersdk.Communicator) (
|
|||
ui.Message("Creating JSON attribute file")
|
||||
|
||||
jsonData := make(map[string]interface{})
|
||||
|
||||
// Copy the configured JSON
|
||||
for k, v := range p.config.Json {
|
||||
jsonData[k] = v
|
||||
}
|
||||
|
||||
// Set the run list if it was specified
|
||||
if len(p.config.RunList) > 0 {
|
||||
jsonData["run_list"] = p.config.RunList
|
||||
|
|
|
@ -29,7 +29,7 @@ type FlatConfig struct {
|
|||
ExecuteCommand *string `mapstructure:"execute_command" cty:"execute_command" hcl:"execute_command"`
|
||||
InstallCommand *string `mapstructure:"install_command" cty:"install_command" hcl:"install_command"`
|
||||
RemoteCookbookPaths []string `mapstructure:"remote_cookbook_paths" cty:"remote_cookbook_paths" hcl:"remote_cookbook_paths"`
|
||||
Json map[string]interface{} `cty:"json" hcl:"json"`
|
||||
JsonString *string `mapstructure:"json_string" cty:"json_string" hcl:"json_string"`
|
||||
PreventSudo *bool `mapstructure:"prevent_sudo" cty:"prevent_sudo" hcl:"prevent_sudo"`
|
||||
RunList []string `mapstructure:"run_list" cty:"run_list" hcl:"run_list"`
|
||||
SkipInstall *bool `mapstructure:"skip_install" cty:"skip_install" hcl:"skip_install"`
|
||||
|
@ -69,7 +69,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"execute_command": &hcldec.AttrSpec{Name: "execute_command", Type: cty.String, Required: false},
|
||||
"install_command": &hcldec.AttrSpec{Name: "install_command", Type: cty.String, Required: false},
|
||||
"remote_cookbook_paths": &hcldec.AttrSpec{Name: "remote_cookbook_paths", Type: cty.List(cty.String), Required: false},
|
||||
"json": &hcldec.AttrSpec{Name: "json", Type: cty.Map(cty.String), Required: false},
|
||||
"json_string": &hcldec.AttrSpec{Name: "json_string", Type: cty.String, Required: false},
|
||||
"prevent_sudo": &hcldec.AttrSpec{Name: "prevent_sudo", Type: cty.Bool, Required: false},
|
||||
"run_list": &hcldec.AttrSpec{Name: "run_list", Type: cty.List(cty.String), Required: false},
|
||||
"skip_install": &hcldec.AttrSpec{Name: "skip_install", Type: cty.Bool, Required: false},
|
||||
|
|
|
@ -356,3 +356,35 @@ func TestProvisionerPrepare_jsonNested(t *testing.T) {
|
|||
t.Fatalf("nope: %#v", fooMap["bar"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvisionerPrepare_jsonstring(t *testing.T) {
|
||||
config := testConfig()
|
||||
config["json_string"] = `{
|
||||
"foo": {
|
||||
"bar": "baz"
|
||||
},
|
||||
"bar": {
|
||||
"bar": "baz"
|
||||
},
|
||||
"bFalse": false,
|
||||
"bTrue": true,
|
||||
"bStr": "bar",
|
||||
"bNil": null,
|
||||
"bInt": 1,
|
||||
"bFloat": 4.5
|
||||
}`
|
||||
|
||||
var p Provisioner
|
||||
err := p.Prepare(config)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
fooMap := p.config.Json["foo"].(map[string]interface{})
|
||||
if fooMap["bar"] != "baz" {
|
||||
t.Fatalf("nope: %#v", fooMap["bar"])
|
||||
}
|
||||
if p.config.Json["bStr"] != "bar" {
|
||||
t.Fatalf("nope: %#v", fooMap["bar"])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,13 +26,29 @@ installed, using the official Chef installers provided by Chef Inc.
|
|||
The example below is fully functional and expects cookbooks in the "cookbooks"
|
||||
directory relative to your working directory.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "chef-solo",
|
||||
"cookbook_paths": ["cookbooks"]
|
||||
<Tabs>
|
||||
<Tab heading="HCL2">
|
||||
|
||||
```hcl
|
||||
provisioner "chef-solo" {
|
||||
cookbook_paths = ["cookbooks"]
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab heading="JSON">
|
||||
|
||||
```json
|
||||
"provisioners":[{
|
||||
"type": "chef-solo",
|
||||
"cookbook_paths": ["cookbooks"]
|
||||
}]
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Configuration Reference
|
||||
|
||||
The reference of available configuration options is listed below. No
|
||||
|
@ -83,9 +99,6 @@ configuration is actually required, but at least `run_list` is recommended.
|
|||
various [configuration template variables](/docs/templates/legacy_json_templates/engine)
|
||||
available. See below for more information.
|
||||
|
||||
- `json` (object) - An arbitrary mapping of JSON that will be available as
|
||||
node attributes while running Chef.
|
||||
|
||||
- `prevent_sudo` (boolean) - By default, the configured commands that are
|
||||
executed to install and run Chef are executed with `sudo`. If this is true,
|
||||
then the sudo will be omitted. This has no effect when guest_os_type is
|
||||
|
@ -115,11 +128,56 @@ configuration is actually required, but at least `run_list` is recommended.
|
|||
able to create directories and write into this folder. If the permissions
|
||||
are not correct, use a shell provisioner prior to this to configure it
|
||||
properly.
|
||||
|
||||
- `version` (string) - The version of Chef to be installed. By default this
|
||||
is empty which will install the latest version of Chef.
|
||||
|
||||
@include 'provisioners/common-config.mdx'
|
||||
|
||||
##### Node Attribute Mapping
|
||||
|
||||
An arbitrary mapping of JSON that will be available as node attributes while running Chef.
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="HCL2">
|
||||
|
||||
- `json_string` (string) - The JSON string can be encoded using the [jsonencode](/docs/templates/hcl_templates/functions/encoding/jsonencode)
|
||||
template function.
|
||||
|
||||
```hcl
|
||||
provisioner "chef-solo" {
|
||||
json_string = jsonencode({
|
||||
"a" = "b"
|
||||
"foo" = {
|
||||
"bar" = "val"
|
||||
"number" = 1
|
||||
}
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab heading="JSON">
|
||||
|
||||
- `json` (object) - This option is only available to old-style JSON templates.
|
||||
|
||||
```json
|
||||
"provisioners":[{
|
||||
"type": "chef-solo",
|
||||
"json": {
|
||||
"a": "b",
|
||||
"foo": {
|
||||
"bar": "val",
|
||||
"number": 1
|
||||
}
|
||||
}
|
||||
}]
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Chef Configuration
|
||||
|
||||
By default, Packer uses a simple Chef configuration file in order to set the
|
||||
|
|
Loading…
Reference in New Issue