diff --git a/command/plugin.go b/command/plugin.go
index 547487f3f..f4b94888a 100644
--- a/command/plugin.go
+++ b/command/plugin.go
@@ -50,8 +50,6 @@ import (
yandeximportpostprocessor "github.com/hashicorp/packer/post-processor/yandex-import"
azuredtlartifactprovisioner "github.com/hashicorp/packer/provisioner/azure-dtlartifact"
breakpointprovisioner "github.com/hashicorp/packer/provisioner/breakpoint"
- chefclientprovisioner "github.com/hashicorp/packer/provisioner/chef-client"
- chefsoloprovisioner "github.com/hashicorp/packer/provisioner/chef-solo"
convergeprovisioner "github.com/hashicorp/packer/provisioner/converge"
fileprovisioner "github.com/hashicorp/packer/provisioner/file"
inspecprovisioner "github.com/hashicorp/packer/provisioner/inspec"
@@ -100,8 +98,6 @@ var Builders = map[string]packersdk.Builder{
var Provisioners = map[string]packersdk.Provisioner{
"azure-dtlartifact": new(azuredtlartifactprovisioner.Provisioner),
"breakpoint": new(breakpointprovisioner.Provisioner),
- "chef-client": new(chefclientprovisioner.Provisioner),
- "chef-solo": new(chefsoloprovisioner.Provisioner),
"converge": new(convergeprovisioner.Provisioner),
"file": new(fileprovisioner.Provisioner),
"inspec": new(inspecprovisioner.Provisioner),
diff --git a/provisioner/chef-client/provisioner.go b/provisioner/chef-client/provisioner.go
deleted file mode 100644
index 9f9b3402e..000000000
--- a/provisioner/chef-client/provisioner.go
+++ /dev/null
@@ -1,782 +0,0 @@
-//go:generate packer-sdc mapstructure-to-hcl2 -type Config
-
-// This package implements a provisioner for Packer that uses
-// Chef to provision the remote machine, specifically with chef-client (that is,
-// with a Chef server).
-package chefclient
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
-
- "github.com/hashicorp/hcl/v2/hcldec"
- "github.com/hashicorp/packer-plugin-sdk/common"
- "github.com/hashicorp/packer-plugin-sdk/guestexec"
- packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
- "github.com/hashicorp/packer-plugin-sdk/pathing"
- "github.com/hashicorp/packer-plugin-sdk/template/config"
- "github.com/hashicorp/packer-plugin-sdk/template/interpolate"
- "github.com/hashicorp/packer-plugin-sdk/uuid"
-)
-
-type guestOSTypeConfig struct {
- executeCommand string
- installCommand string
- knifeCommand string
- stagingDir string
-}
-
-var guestOSTypeConfigs = map[string]guestOSTypeConfig{
- guestexec.UnixOSType: {
- executeCommand: "{{if .Sudo}}sudo {{end}}chef-client --no-color -c {{.ConfigPath}} -j {{.JsonPath}}",
- installCommand: "curl -L https://omnitruck.chef.io/install.sh | {{if .Sudo}}sudo {{end}}bash -s --{{if .Version}} -v {{.Version}}{{end}}",
- knifeCommand: "{{if .Sudo}}sudo {{end}}knife {{.Args}} {{.Flags}}",
- stagingDir: "/tmp/packer-chef-client",
- },
- guestexec.WindowsOSType: {
- executeCommand: "c:/opscode/chef/bin/chef-client.bat --no-color -c {{.ConfigPath}} -j {{.JsonPath}}",
- installCommand: "powershell.exe -Command \". { iwr -useb https://omnitruck.chef.io/install.ps1 } | iex; Install-Project{{if .Version}} -version {{.Version}}{{end}}\"",
- knifeCommand: "c:/opscode/chef/bin/knife.bat {{.Args}} {{.Flags}}",
- stagingDir: "C:/Windows/Temp/packer-chef-client",
- },
-}
-
-type Config struct {
- common.PackerConfig `mapstructure:",squash"`
-
- Json map[string]interface{}
-
- ChefEnvironment string `mapstructure:"chef_environment"`
- ChefLicense string `mapstructure:"chef_license"`
- ClientKey string `mapstructure:"client_key"`
- ConfigTemplate string `mapstructure:"config_template"`
- ElevatedUser string `mapstructure:"elevated_user"`
- ElevatedPassword string `mapstructure:"elevated_password"`
- EncryptedDataBagSecretPath string `mapstructure:"encrypted_data_bag_secret_path"`
- ExecuteCommand string `mapstructure:"execute_command"`
- GuestOSType string `mapstructure:"guest_os_type"`
- InstallCommand string `mapstructure:"install_command"`
- KnifeCommand string `mapstructure:"knife_command"`
- NodeName string `mapstructure:"node_name"`
- PolicyGroup string `mapstructure:"policy_group"`
- PolicyName string `mapstructure:"policy_name"`
- PreventSudo bool `mapstructure:"prevent_sudo"`
- RunList []string `mapstructure:"run_list"`
- ServerUrl string `mapstructure:"server_url"`
- SkipCleanClient bool `mapstructure:"skip_clean_client"`
- SkipCleanNode bool `mapstructure:"skip_clean_node"`
- SkipCleanStagingDirectory bool `mapstructure:"skip_clean_staging_directory"`
- SkipInstall bool `mapstructure:"skip_install"`
- SslVerifyMode string `mapstructure:"ssl_verify_mode"`
- TrustedCertsDir string `mapstructure:"trusted_certs_dir"`
- StagingDir string `mapstructure:"staging_directory"`
- ValidationClientName string `mapstructure:"validation_client_name"`
- ValidationKeyPath string `mapstructure:"validation_key_path"`
- Version string `mapstructure:"version"`
-
- ctx interpolate.Context
-}
-
-type Provisioner struct {
- config Config
- communicator packersdk.Communicator
- guestOSTypeConfig guestOSTypeConfig
- guestCommands *guestexec.GuestCommands
- generatedData map[string]interface{}
-}
-
-type ConfigTemplate struct {
- ChefEnvironment string
- ChefLicense string
- ClientKey string
- EncryptedDataBagSecretPath string
- NodeName string
- PolicyGroup string
- PolicyName string
- ServerUrl string
- SslVerifyMode string
- TrustedCertsDir string
- ValidationClientName string
- ValidationKeyPath string
-}
-
-type ExecuteTemplate struct {
- ConfigPath string
- JsonPath string
- Sudo bool
-}
-
-type InstallChefTemplate struct {
- Sudo bool
- Version string
-}
-
-type KnifeTemplate struct {
- Sudo bool
- Flags string
- Args string
-}
-
-func (p *Provisioner) ConfigSpec() hcldec.ObjectSpec { return p.config.FlatMapstructure().HCL2Spec() }
-
-func (p *Provisioner) Prepare(raws ...interface{}) error {
- err := config.Decode(&p.config, &config.DecodeOpts{
- PluginType: "chef-client",
- Interpolate: true,
- InterpolateContext: &p.config.ctx,
- InterpolateFilter: &interpolate.RenderFilter{
- Exclude: []string{
- "execute_command",
- "install_command",
- "knife_command",
- },
- },
- }, raws...)
- if err != nil {
- return err
- }
-
- if p.config.GuestOSType == "" {
- p.config.GuestOSType = guestexec.DefaultOSType
- }
- p.config.GuestOSType = strings.ToLower(p.config.GuestOSType)
-
- var ok bool
- p.guestOSTypeConfig, ok = guestOSTypeConfigs[p.config.GuestOSType]
- if !ok {
- return fmt.Errorf("Invalid guest_os_type: \"%s\"", p.config.GuestOSType)
- }
-
- p.guestCommands, err = guestexec.NewGuestCommands(p.config.GuestOSType, !p.config.PreventSudo)
- if err != nil {
- return fmt.Errorf("Invalid guest_os_type: \"%s\"", p.config.GuestOSType)
- }
-
- if p.config.ExecuteCommand == "" {
- p.config.ExecuteCommand = p.guestOSTypeConfig.executeCommand
- }
-
- if p.config.InstallCommand == "" {
- p.config.InstallCommand = p.guestOSTypeConfig.installCommand
- }
-
- if p.config.RunList == nil {
- p.config.RunList = make([]string, 0)
- }
-
- if p.config.StagingDir == "" {
- p.config.StagingDir = p.guestOSTypeConfig.stagingDir
- }
-
- if p.config.KnifeCommand == "" {
- p.config.KnifeCommand = p.guestOSTypeConfig.knifeCommand
- }
-
- var errs *packersdk.MultiError
- if p.config.ConfigTemplate != "" {
- fi, err := os.Stat(p.config.ConfigTemplate)
- if err != nil {
- errs = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("Bad config template path: %s", err))
- } else if fi.IsDir() {
- errs = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("Config template path must be a file: %s", err))
- }
- }
-
- if p.config.ServerUrl == "" {
- errs = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("server_url must be set"))
- }
-
- if p.config.SkipInstall == false && p.config.InstallCommand == p.guestOSTypeConfig.installCommand {
- if p.config.ChefLicense == "" {
- p.config.ChefLicense = "accept-silent"
- }
- }
-
- if p.config.EncryptedDataBagSecretPath != "" {
- pFileInfo, err := os.Stat(p.config.EncryptedDataBagSecretPath)
-
- if err != nil || pFileInfo.IsDir() {
- errs = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("Bad encrypted data bag secret '%s': %s", p.config.EncryptedDataBagSecretPath, err))
- }
- }
-
- if (p.config.PolicyName != "") != (p.config.PolicyGroup != "") {
- errs = packersdk.MultiErrorAppend(errs, fmt.Errorf("If either policy_name or policy_group are set, they must both be set."))
- }
-
- jsonValid := true
- for k, v := range p.config.Json {
- p.config.Json[k], err = p.deepJsonFix(k, v)
- if err != nil {
- errs = packersdk.MultiErrorAppend(
- 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 = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("Error processing user variables in JSON: %s", err))
- }
- }
-
- if errs != nil && len(errs.Errors) > 0 {
- return errs
- }
-
- return nil
-}
-
-func (p *Provisioner) Provision(ctx context.Context, ui packersdk.Ui, comm packersdk.Communicator, generatedData map[string]interface{}) error {
- p.generatedData = generatedData
- p.communicator = comm
-
- nodeName := p.config.NodeName
- if nodeName == "" {
- nodeName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID())
- }
- remoteValidationKeyPath := ""
- serverUrl := p.config.ServerUrl
-
- if !p.config.SkipInstall {
- if err := p.installChef(ui, comm, p.config.Version); err != nil {
- return fmt.Errorf("Error installing Chef: %s", err)
- }
- }
-
- if err := p.createDir(ui, comm, p.config.StagingDir); err != nil {
- return fmt.Errorf("Error creating staging directory: %s", err)
- }
-
- if p.config.ClientKey == "" {
- p.config.ClientKey = fmt.Sprintf("%s/client.pem", p.config.StagingDir)
- }
-
- encryptedDataBagSecretPath := ""
- if p.config.EncryptedDataBagSecretPath != "" {
- encryptedDataBagSecretPath = fmt.Sprintf("%s/encrypted_data_bag_secret", p.config.StagingDir)
- if err := p.uploadFile(ui,
- comm,
- encryptedDataBagSecretPath,
- p.config.EncryptedDataBagSecretPath); err != nil {
- return fmt.Errorf("Error uploading encrypted data bag secret: %s", err)
- }
- }
-
- if p.config.ValidationKeyPath != "" {
- path, err := pathing.ExpandUser(p.config.ValidationKeyPath)
- if err != nil {
- return fmt.Errorf("Error while expanding a tilde in the validation key: %s", err)
- }
- remoteValidationKeyPath = fmt.Sprintf("%s/validation.pem", p.config.StagingDir)
- if err := p.uploadFile(ui, comm, remoteValidationKeyPath, path); err != nil {
- return fmt.Errorf("Error copying validation key: %s", err)
- }
- }
-
- configPath, err := p.createConfig(
- ui,
- comm,
- nodeName,
- serverUrl,
- p.config.ClientKey,
- p.config.ChefLicense,
- encryptedDataBagSecretPath,
- remoteValidationKeyPath,
- p.config.ValidationClientName,
- p.config.ChefEnvironment,
- p.config.PolicyGroup,
- p.config.PolicyName,
- p.config.SslVerifyMode,
- p.config.TrustedCertsDir)
- if err != nil {
- return fmt.Errorf("Error creating Chef config file: %s", err)
- }
-
- jsonPath, err := p.createJson(ui, comm)
- if err != nil {
- return fmt.Errorf("Error creating JSON attributes: %s", err)
- }
-
- err = p.executeChef(ui, comm, configPath, jsonPath)
-
- if !(p.config.SkipCleanNode && p.config.SkipCleanClient) {
-
- knifeConfigPath, knifeErr := p.createKnifeConfig(
- ui, comm, nodeName, serverUrl, p.config.ClientKey, p.config.SslVerifyMode, p.config.TrustedCertsDir)
-
- if knifeErr != nil {
- return fmt.Errorf("Error creating knife config on node: %s", knifeErr)
- }
-
- if !p.config.SkipCleanNode {
- if err := p.cleanNode(ui, comm, nodeName, knifeConfigPath); err != nil {
- return fmt.Errorf("Error cleaning up chef node: %s", err)
- }
- }
-
- if !p.config.SkipCleanClient {
- if err := p.cleanClient(ui, comm, nodeName, knifeConfigPath); err != nil {
- return fmt.Errorf("Error cleaning up chef client: %s", err)
- }
- }
- }
-
- if err != nil {
- return fmt.Errorf("Error executing Chef: %s", err)
- }
-
- if !p.config.SkipCleanStagingDirectory {
- if err := p.removeDir(ui, comm, p.config.StagingDir); err != nil {
- return fmt.Errorf("Error removing %s: %s", p.config.StagingDir, err)
- }
- }
-
- return nil
-}
-
-func (p *Provisioner) uploadFile(ui packersdk.Ui, comm packersdk.Communicator, remotePath string, localPath string) error {
- ui.Message(fmt.Sprintf("Uploading %s...", localPath))
-
- f, err := os.Open(localPath)
- if err != nil {
- return err
- }
- defer f.Close()
-
- return comm.Upload(remotePath, f, nil)
-}
-
-func (p *Provisioner) createConfig(
- ui packersdk.Ui,
- comm packersdk.Communicator,
- nodeName string,
- serverUrl string,
- clientKey string,
- chefLicense string,
- encryptedDataBagSecretPath,
- remoteKeyPath string,
- validationClientName string,
- chefEnvironment string,
- policyGroup string,
- policyName string,
- sslVerifyMode string,
- trustedCertsDir string) (string, error) {
-
- ui.Message("Creating configuration file 'client.rb'")
-
- // Read the template
- tpl := DefaultConfigTemplate
- if p.config.ConfigTemplate != "" {
- f, err := os.Open(p.config.ConfigTemplate)
- if err != nil {
- return "", err
- }
- defer f.Close()
-
- tplBytes, err := ioutil.ReadAll(f)
- if err != nil {
- return "", err
- }
-
- tpl = string(tplBytes)
- }
-
- ictx := p.config.ctx
- ictx.Data = &ConfigTemplate{
- NodeName: nodeName,
- ServerUrl: serverUrl,
- ClientKey: clientKey,
- ChefLicense: chefLicense,
- ValidationKeyPath: remoteKeyPath,
- ValidationClientName: validationClientName,
- ChefEnvironment: chefEnvironment,
- PolicyGroup: policyGroup,
- PolicyName: policyName,
- SslVerifyMode: sslVerifyMode,
- TrustedCertsDir: trustedCertsDir,
- EncryptedDataBagSecretPath: encryptedDataBagSecretPath,
- }
- configString, err := interpolate.Render(tpl, &ictx)
- if err != nil {
- return "", err
- }
-
- remotePath := filepath.ToSlash(filepath.Join(p.config.StagingDir, "client.rb"))
- if err := comm.Upload(remotePath, bytes.NewReader([]byte(configString)), nil); err != nil {
- return "", err
- }
-
- return remotePath, nil
-}
-
-func (p *Provisioner) createKnifeConfig(ui packersdk.Ui, comm packersdk.Communicator, nodeName string, serverUrl string, clientKey string, sslVerifyMode string, trustedCertsDir string) (string, error) {
- ui.Message("Creating configuration file 'knife.rb'")
-
- // Read the template
- tpl := DefaultKnifeTemplate
-
- ictx := p.config.ctx
- ictx.Data = &ConfigTemplate{
- NodeName: nodeName,
- ServerUrl: serverUrl,
- ClientKey: clientKey,
- SslVerifyMode: sslVerifyMode,
- TrustedCertsDir: trustedCertsDir,
- }
- configString, err := interpolate.Render(tpl, &ictx)
- if err != nil {
- return "", err
- }
-
- remotePath := filepath.ToSlash(filepath.Join(p.config.StagingDir, "knife.rb"))
- if err := comm.Upload(remotePath, bytes.NewReader([]byte(configString)), nil); err != nil {
- return "", err
- }
-
- return remotePath, nil
-}
-
-func (p *Provisioner) createJson(ui packersdk.Ui, comm packersdk.Communicator) (string, error) {
- 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
- }
-
- jsonBytes, err := json.MarshalIndent(jsonData, "", " ")
- if err != nil {
- return "", err
- }
-
- // Upload the bytes
- remotePath := filepath.ToSlash(filepath.Join(p.config.StagingDir, "first-boot.json"))
- if err := comm.Upload(remotePath, bytes.NewReader(jsonBytes), nil); err != nil {
- return "", err
- }
-
- return remotePath, nil
-}
-
-func (p *Provisioner) createDir(ui packersdk.Ui, comm packersdk.Communicator, dir string) error {
- ctx := context.TODO()
- ui.Message(fmt.Sprintf("Creating directory: %s", dir))
-
- cmd := &packersdk.RemoteCmd{Command: p.guestCommands.CreateDir(dir)}
- if err := cmd.RunWithUi(ctx, 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
- cmd = &packersdk.RemoteCmd{Command: p.guestCommands.Chmod(dir, "0777")}
- if err := cmd.RunWithUi(ctx, comm, ui); err != nil {
- return err
- }
- if cmd.ExitStatus() != 0 {
- return fmt.Errorf("Non-zero exit status. See output above for more info.")
- }
-
- return nil
-}
-
-func (p *Provisioner) cleanNode(ui packersdk.Ui, comm packersdk.Communicator, node string, knifeConfigPath string) error {
- ui.Say("Cleaning up chef node...")
- args := []string{"node", "delete", node}
- if err := p.knifeExec(ui, comm, node, knifeConfigPath, args); err != nil {
- return fmt.Errorf("Failed to cleanup node: %s", err)
- }
-
- return nil
-}
-
-func (p *Provisioner) cleanClient(ui packersdk.Ui, comm packersdk.Communicator, node string, knifeConfigPath string) error {
- ui.Say("Cleaning up chef client...")
- args := []string{"client", "delete", node}
- if err := p.knifeExec(ui, comm, node, knifeConfigPath, args); err != nil {
- return fmt.Errorf("Failed to cleanup client: %s", err)
- }
-
- return nil
-}
-
-func (p *Provisioner) knifeExec(ui packersdk.Ui, comm packersdk.Communicator, node string, knifeConfigPath string, args []string) error {
- flags := []string{
- "-y",
- "-c", knifeConfigPath,
- }
- ctx := context.TODO()
-
- p.config.ctx.Data = &KnifeTemplate{
- Sudo: !p.config.PreventSudo,
- Flags: strings.Join(flags, " "),
- Args: strings.Join(args, " "),
- }
-
- command, err := interpolate.Render(p.config.KnifeCommand, &p.config.ctx)
- if err != nil {
- return err
- }
-
- cmd := &packersdk.RemoteCmd{Command: command}
- if err := cmd.RunWithUi(ctx, comm, ui); err != nil {
- return err
- }
- if cmd.ExitStatus() != 0 {
- return fmt.Errorf(
- "Non-zero exit status. See output above for more info.\n\n"+
- "Command: %s",
- command)
- }
-
- return nil
-}
-
-func (p *Provisioner) removeDir(ui packersdk.Ui, comm packersdk.Communicator, dir string) error {
- ui.Message(fmt.Sprintf("Removing directory: %s", dir))
- ctx := context.TODO()
-
- cmd := &packersdk.RemoteCmd{Command: p.guestCommands.RemoveDir(dir)}
- if err := cmd.RunWithUi(ctx, comm, ui); err != nil {
- return err
- }
-
- return nil
-}
-
-func (p *Provisioner) executeChef(ui packersdk.Ui, comm packersdk.Communicator, config string, json string) error {
- p.config.ctx.Data = &ExecuteTemplate{
- ConfigPath: config,
- JsonPath: json,
- Sudo: !p.config.PreventSudo,
- }
- ctx := context.TODO()
-
- command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx)
- if err != nil {
- return err
- }
-
- if p.config.ElevatedUser != "" {
- command, err = guestexec.GenerateElevatedRunner(command, p)
- if err != nil {
- return err
- }
- }
-
- ui.Message(fmt.Sprintf("Executing Chef: %s", command))
-
- cmd := &packersdk.RemoteCmd{
- Command: command,
- }
-
- if err := cmd.RunWithUi(ctx, comm, ui); err != nil {
- return err
- }
-
- if cmd.ExitStatus() != 0 {
- return fmt.Errorf("Non-zero exit status: %d", cmd.ExitStatus())
- }
-
- return nil
-}
-
-func (p *Provisioner) installChef(ui packersdk.Ui, comm packersdk.Communicator, version string) error {
- ui.Message("Installing Chef...")
- ctx := context.TODO()
-
- p.config.ctx.Data = &InstallChefTemplate{
- Sudo: !p.config.PreventSudo,
- Version: version,
- }
- command, err := interpolate.Render(p.config.InstallCommand, &p.config.ctx)
- if err != nil {
- return err
- }
-
- ui.Message(command)
-
- cmd := &packersdk.RemoteCmd{Command: command}
- if err := cmd.RunWithUi(ctx, comm, ui); err != nil {
- return err
- }
-
- if cmd.ExitStatus() != 0 {
- return fmt.Errorf(
- "Install script exited with non-zero exit status %d", cmd.ExitStatus())
- }
-
- 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 []uint8:
- return string(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
- default:
- return current, 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.ctx.UserVariables {
- originalUserVars[k] = v
- }
-
- // Make sure we reset them no matter what
- defer func() {
- p.config.ctx.UserVariables = originalUserVars
- }()
-
- // Make the current user variables JSON string safe.
- for k, v := range p.config.ctx.UserVariables {
- v = strings.Replace(v, `\`, `\\`, -1)
- v = strings.Replace(v, `"`, `\"`, -1)
- p.config.ctx.UserVariables[k] = v
- }
-
- // Process the bytes with the template processor
- p.config.ctx.Data = nil
- jsonBytesProcessed, err := interpolate.Render(string(jsonBytes), &p.config.ctx)
- 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) Communicator() packersdk.Communicator {
- return p.communicator
-}
-
-func (p *Provisioner) ElevatedUser() string {
- return p.config.ElevatedUser
-}
-
-func (p *Provisioner) ElevatedPassword() string {
- // Replace ElevatedPassword for winrm users who used this feature
- p.config.ctx.Data = p.generatedData
-
- elevatedPassword, _ := interpolate.Render(p.config.ElevatedPassword, &p.config.ctx)
-
- return elevatedPassword
-}
-
-var DefaultConfigTemplate = `
-log_level :info
-log_location STDOUT
-chef_server_url "{{.ServerUrl}}"
-client_key "{{.ClientKey}}"
-chef_license "{{.ChefLicense}}"
-{{if ne .EncryptedDataBagSecretPath ""}}
-encrypted_data_bag_secret "{{.EncryptedDataBagSecretPath}}"
-{{end}}
-{{if ne .ValidationClientName ""}}
-validation_client_name "{{.ValidationClientName}}"
-{{else}}
-validation_client_name "chef-validator"
-{{end}}
-{{if ne .ValidationKeyPath ""}}
-validation_key "{{.ValidationKeyPath}}"
-{{end}}
-node_name "{{.NodeName}}"
-{{if ne .ChefEnvironment ""}}
-environment "{{.ChefEnvironment}}"
-{{end}}
-{{if ne .PolicyGroup ""}}
-policy_group "{{.PolicyGroup}}"
-{{end}}
-{{if ne .PolicyName ""}}
-policy_name "{{.PolicyName}}"
-{{end}}
-{{if ne .SslVerifyMode ""}}
-ssl_verify_mode :{{.SslVerifyMode}}
-{{end}}
-{{if ne .TrustedCertsDir ""}}
-trusted_certs_dir "{{.TrustedCertsDir}}"
-{{end}}
-`
-
-var DefaultKnifeTemplate = `
-log_level :info
-log_location STDOUT
-chef_server_url "{{.ServerUrl}}"
-client_key "{{.ClientKey}}"
-node_name "{{.NodeName}}"
-{{if ne .SslVerifyMode ""}}
-ssl_verify_mode :{{.SslVerifyMode}}
-{{end}}
-{{if ne .TrustedCertsDir ""}}
-trusted_certs_dir "{{.TrustedCertsDir}}"
-{{end}}
-`
diff --git a/provisioner/chef-client/provisioner.hcl2spec.go b/provisioner/chef-client/provisioner.hcl2spec.go
deleted file mode 100644
index 96d3eae6e..000000000
--- a/provisioner/chef-client/provisioner.hcl2spec.go
+++ /dev/null
@@ -1,101 +0,0 @@
-// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
-
-package chefclient
-
-import (
- "github.com/hashicorp/hcl/v2/hcldec"
- "github.com/zclconf/go-cty/cty"
-)
-
-// FlatConfig is an auto-generated flat version of Config.
-// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
-type FlatConfig struct {
- PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
- PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
- PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"`
- PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
- PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
- PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
- PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"`
- PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"`
- Json map[string]interface{} `cty:"json" hcl:"json"`
- ChefEnvironment *string `mapstructure:"chef_environment" cty:"chef_environment" hcl:"chef_environment"`
- ChefLicense *string `mapstructure:"chef_license" cty:"chef_license" hcl:"chef_license"`
- ClientKey *string `mapstructure:"client_key" cty:"client_key" hcl:"client_key"`
- ConfigTemplate *string `mapstructure:"config_template" cty:"config_template" hcl:"config_template"`
- ElevatedUser *string `mapstructure:"elevated_user" cty:"elevated_user" hcl:"elevated_user"`
- ElevatedPassword *string `mapstructure:"elevated_password" cty:"elevated_password" hcl:"elevated_password"`
- EncryptedDataBagSecretPath *string `mapstructure:"encrypted_data_bag_secret_path" cty:"encrypted_data_bag_secret_path" hcl:"encrypted_data_bag_secret_path"`
- ExecuteCommand *string `mapstructure:"execute_command" cty:"execute_command" hcl:"execute_command"`
- GuestOSType *string `mapstructure:"guest_os_type" cty:"guest_os_type" hcl:"guest_os_type"`
- InstallCommand *string `mapstructure:"install_command" cty:"install_command" hcl:"install_command"`
- KnifeCommand *string `mapstructure:"knife_command" cty:"knife_command" hcl:"knife_command"`
- NodeName *string `mapstructure:"node_name" cty:"node_name" hcl:"node_name"`
- PolicyGroup *string `mapstructure:"policy_group" cty:"policy_group" hcl:"policy_group"`
- PolicyName *string `mapstructure:"policy_name" cty:"policy_name" hcl:"policy_name"`
- PreventSudo *bool `mapstructure:"prevent_sudo" cty:"prevent_sudo" hcl:"prevent_sudo"`
- RunList []string `mapstructure:"run_list" cty:"run_list" hcl:"run_list"`
- ServerUrl *string `mapstructure:"server_url" cty:"server_url" hcl:"server_url"`
- SkipCleanClient *bool `mapstructure:"skip_clean_client" cty:"skip_clean_client" hcl:"skip_clean_client"`
- SkipCleanNode *bool `mapstructure:"skip_clean_node" cty:"skip_clean_node" hcl:"skip_clean_node"`
- SkipCleanStagingDirectory *bool `mapstructure:"skip_clean_staging_directory" cty:"skip_clean_staging_directory" hcl:"skip_clean_staging_directory"`
- SkipInstall *bool `mapstructure:"skip_install" cty:"skip_install" hcl:"skip_install"`
- SslVerifyMode *string `mapstructure:"ssl_verify_mode" cty:"ssl_verify_mode" hcl:"ssl_verify_mode"`
- TrustedCertsDir *string `mapstructure:"trusted_certs_dir" cty:"trusted_certs_dir" hcl:"trusted_certs_dir"`
- StagingDir *string `mapstructure:"staging_directory" cty:"staging_directory" hcl:"staging_directory"`
- ValidationClientName *string `mapstructure:"validation_client_name" cty:"validation_client_name" hcl:"validation_client_name"`
- ValidationKeyPath *string `mapstructure:"validation_key_path" cty:"validation_key_path" hcl:"validation_key_path"`
- Version *string `mapstructure:"version" cty:"version" hcl:"version"`
-}
-
-// FlatMapstructure returns a new FlatConfig.
-// FlatConfig is an auto-generated flat version of Config.
-// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
-func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
- return new(FlatConfig)
-}
-
-// HCL2Spec returns the hcl spec of a Config.
-// This spec is used by HCL to read the fields of Config.
-// The decoded values from this spec will then be applied to a FlatConfig.
-func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
- s := map[string]hcldec.Spec{
- "packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
- "packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
- "packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false},
- "packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
- "packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
- "packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
- "packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false},
- "packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
- "json": &hcldec.AttrSpec{Name: "json", Type: cty.Map(cty.String), Required: false},
- "chef_environment": &hcldec.AttrSpec{Name: "chef_environment", Type: cty.String, Required: false},
- "chef_license": &hcldec.AttrSpec{Name: "chef_license", Type: cty.String, Required: false},
- "client_key": &hcldec.AttrSpec{Name: "client_key", Type: cty.String, Required: false},
- "config_template": &hcldec.AttrSpec{Name: "config_template", Type: cty.String, Required: false},
- "elevated_user": &hcldec.AttrSpec{Name: "elevated_user", Type: cty.String, Required: false},
- "elevated_password": &hcldec.AttrSpec{Name: "elevated_password", Type: cty.String, Required: false},
- "encrypted_data_bag_secret_path": &hcldec.AttrSpec{Name: "encrypted_data_bag_secret_path", Type: cty.String, Required: false},
- "execute_command": &hcldec.AttrSpec{Name: "execute_command", Type: cty.String, Required: false},
- "guest_os_type": &hcldec.AttrSpec{Name: "guest_os_type", Type: cty.String, Required: false},
- "install_command": &hcldec.AttrSpec{Name: "install_command", Type: cty.String, Required: false},
- "knife_command": &hcldec.AttrSpec{Name: "knife_command", Type: cty.String, Required: false},
- "node_name": &hcldec.AttrSpec{Name: "node_name", Type: cty.String, Required: false},
- "policy_group": &hcldec.AttrSpec{Name: "policy_group", Type: cty.String, Required: false},
- "policy_name": &hcldec.AttrSpec{Name: "policy_name", 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},
- "server_url": &hcldec.AttrSpec{Name: "server_url", Type: cty.String, Required: false},
- "skip_clean_client": &hcldec.AttrSpec{Name: "skip_clean_client", Type: cty.Bool, Required: false},
- "skip_clean_node": &hcldec.AttrSpec{Name: "skip_clean_node", Type: cty.Bool, Required: false},
- "skip_clean_staging_directory": &hcldec.AttrSpec{Name: "skip_clean_staging_directory", Type: cty.Bool, Required: false},
- "skip_install": &hcldec.AttrSpec{Name: "skip_install", Type: cty.Bool, Required: false},
- "ssl_verify_mode": &hcldec.AttrSpec{Name: "ssl_verify_mode", Type: cty.String, Required: false},
- "trusted_certs_dir": &hcldec.AttrSpec{Name: "trusted_certs_dir", Type: cty.String, Required: false},
- "staging_directory": &hcldec.AttrSpec{Name: "staging_directory", Type: cty.String, Required: false},
- "validation_client_name": &hcldec.AttrSpec{Name: "validation_client_name", Type: cty.String, Required: false},
- "validation_key_path": &hcldec.AttrSpec{Name: "validation_key_path", Type: cty.String, Required: false},
- "version": &hcldec.AttrSpec{Name: "version", Type: cty.String, Required: false},
- }
- return s
-}
diff --git a/provisioner/chef-client/provisioner_test.go b/provisioner/chef-client/provisioner_test.go
deleted file mode 100644
index 2b569314f..000000000
--- a/provisioner/chef-client/provisioner_test.go
+++ /dev/null
@@ -1,322 +0,0 @@
-package chefclient
-
-import (
- "bytes"
- "io/ioutil"
- "os"
- "strings"
- "testing"
-
- packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
-)
-
-func testConfig() map[string]interface{} {
- return map[string]interface{}{
- "server_url": "foo",
- }
-}
-
-func TestProvisioner_Impl(t *testing.T) {
- var raw interface{}
- raw = &Provisioner{}
- if _, ok := raw.(packersdk.Provisioner); !ok {
- t.Fatalf("must be a Provisioner")
- }
-}
-
-func TestProvisionerPrepare_chefEnvironment(t *testing.T) {
- var p Provisioner
-
- config := testConfig()
- config["chef_environment"] = "some-env"
-
- err := p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if p.config.ChefEnvironment != "some-env" {
- t.Fatalf("unexpected: %#v", p.config.ChefEnvironment)
- }
-}
-
-func TestProvisionerPrepare_configTemplate(t *testing.T) {
- var err error
- var p Provisioner
-
- // Test no config template
- config := testConfig()
- delete(config, "config_template")
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- // Test with a file
- tf, err := ioutil.TempFile("", "packer")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer os.Remove(tf.Name())
-
- config = testConfig()
- config["config_template"] = tf.Name()
- p = Provisioner{}
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- // Test with a directory
- td, err := ioutil.TempDir("", "packer")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer os.RemoveAll(td)
-
- config = testConfig()
- config["config_template"] = td
- p = Provisioner{}
- err = p.Prepare(config)
- if err == nil {
- t.Fatal("should have err")
- }
-}
-
-func TestProvisionerPrepare_commands(t *testing.T) {
- commands := []string{
- "execute_command",
- "install_command",
- "knife_command",
- }
-
- for _, command := range commands {
- var p Provisioner
-
- // Test not set
- config := testConfig()
- delete(config, command)
- err := p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- // Test invalid template
- config = testConfig()
- config[command] = "{{if NOPE}}"
- err = p.Prepare(config)
- if err == nil {
- t.Fatal("should error")
- }
-
- // Test good template
- config = testConfig()
- config[command] = "{{.Foo}}"
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- }
-}
-
-func TestProvisionerPrepare_serverUrl(t *testing.T) {
- var p Provisioner
-
- // Test not set
- config := testConfig()
- delete(config, "server_url")
- err := p.Prepare(config)
- if err == nil {
- t.Fatal("should error")
- }
-
- // Test set
- config = testConfig()
- config["server_url"] = "foo"
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-}
-func TestProvisionerPrepare_chefLicense(t *testing.T) {
- var p Provisioner
-
- // Test not set
- config := testConfig()
- err := p.Prepare(config)
- if err != nil {
- t.Fatal("should error")
- }
-
- if p.config.ChefLicense != "accept-silent" {
- t.Fatalf("unexpected: %#v", p.config.ChefLicense)
- }
-
- // Test set
- config = testConfig()
- config["chef_license"] = "accept"
- p = Provisioner{}
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if p.config.ChefLicense != "accept" {
- t.Fatalf("unexpected: %#v", p.config.ChefLicense)
- }
-
- // Test set skipInstall true
- config = testConfig()
- config["skip_install"] = true
- p = Provisioner{}
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if p.config.ChefLicense != "" {
- t.Fatalf("unexpected: %#v", "empty string")
- }
-
- // Test set installCommand true
- config = testConfig()
- config["install_command"] = "install chef"
- p = Provisioner{}
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if p.config.ChefLicense != "" {
- t.Fatalf("unexpected: %#v", "empty string")
- }
-}
-
-func TestProvisionerPrepare_encryptedDataBagSecretPath(t *testing.T) {
- var err error
- var p Provisioner
-
- // Test no config template
- config := testConfig()
- delete(config, "encrypted_data_bag_secret_path")
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- // Test with a file
- tf, err := ioutil.TempFile("", "packer")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer os.Remove(tf.Name())
-
- config = testConfig()
- config["encrypted_data_bag_secret_path"] = tf.Name()
- p = Provisioner{}
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- // Test with a directory
- td, err := ioutil.TempDir("", "packer")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer os.RemoveAll(td)
-
- config = testConfig()
- config["encrypted_data_bag_secret_path"] = td
- p = Provisioner{}
- err = p.Prepare(config)
- if err == nil {
- t.Fatal("should have err")
- }
-}
-
-func TestProvisioner_createDir(t *testing.T) {
- for _, sudo := range []bool{true, false} {
- config := testConfig()
- config["prevent_sudo"] = !sudo
-
- p := &Provisioner{}
- comm := &packersdk.MockCommunicator{}
- ui := &packersdk.BasicUi{
- Reader: new(bytes.Buffer),
- Writer: new(bytes.Buffer),
- }
-
- err := p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if err := p.createDir(ui, comm, "/tmp/foo"); err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if !sudo && strings.HasPrefix(comm.StartCmd.Command, "sudo") {
- t.Fatalf("createDir should not use sudo, got: \"%s\"", comm.StartCmd.Command)
- }
-
- if sudo && !strings.HasPrefix(comm.StartCmd.Command, "sudo") {
- t.Fatalf("createDir should use sudo, got: \"%s\"", comm.StartCmd.Command)
- }
- }
-}
-
-func TestProvisioner_removeDir(t *testing.T) {
- for _, sudo := range []bool{true, false} {
- config := testConfig()
- config["prevent_sudo"] = !sudo
-
- p := &Provisioner{}
- comm := &packersdk.MockCommunicator{}
- ui := &packersdk.BasicUi{
- Reader: new(bytes.Buffer),
- Writer: new(bytes.Buffer),
- }
-
- err := p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if err := p.removeDir(ui, comm, "/tmp/foo"); err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if !sudo && strings.HasPrefix(comm.StartCmd.Command, "sudo") {
- t.Fatalf("removeDir should not use sudo, got: \"%s\"", comm.StartCmd.Command)
- }
-
- if sudo && !strings.HasPrefix(comm.StartCmd.Command, "sudo") {
- t.Fatalf("removeDir should use sudo, got: \"%s\"", comm.StartCmd.Command)
- }
- }
-}
-
-func TestProvisionerPrepare_policy(t *testing.T) {
- var p Provisioner
-
- var policyTests = []struct {
- name string
- group string
- success bool
- }{
- {"", "", true},
- {"a", "b", true},
- {"a", "", false},
- {"", "a", false},
- }
- for _, tt := range policyTests {
- config := testConfig()
- config["policy_name"] = tt.name
- config["policy_group"] = tt.group
- err := p.Prepare(config)
- if (err == nil) != tt.success {
- t.Fatalf("wasn't expecting %+v to fail: %s", tt, err.Error())
- }
- }
-}
diff --git a/provisioner/chef-client/version/version.go b/provisioner/chef-client/version/version.go
deleted file mode 100644
index f3cf16c4d..000000000
--- a/provisioner/chef-client/version/version.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package version
-
-import (
- "github.com/hashicorp/packer-plugin-sdk/version"
- packerVersion "github.com/hashicorp/packer/version"
-)
-
-var ChefClientPluginVersion *version.PluginVersion
-
-func init() {
- ChefClientPluginVersion = version.InitializePluginVersion(
- packerVersion.Version, packerVersion.VersionPrerelease)
-}
diff --git a/provisioner/chef-solo/provisioner.go b/provisioner/chef-solo/provisioner.go
deleted file mode 100644
index abe102906..000000000
--- a/provisioner/chef-solo/provisioner.go
+++ /dev/null
@@ -1,611 +0,0 @@
-//go:generate packer-sdc mapstructure-to-hcl2 -type Config
-
-// This package implements a provisioner for Packer that uses
-// Chef to provision the remote machine, specifically with chef-solo (that is,
-// without a Chef server).
-package chefsolo
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
-
- "github.com/hashicorp/hcl/v2/hcldec"
- "github.com/hashicorp/packer-plugin-sdk/common"
- "github.com/hashicorp/packer-plugin-sdk/guestexec"
- packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
- "github.com/hashicorp/packer-plugin-sdk/template/config"
- "github.com/hashicorp/packer-plugin-sdk/template/interpolate"
-)
-
-type guestOSTypeConfig struct {
- executeCommand string
- installCommand string
- stagingDir string
-}
-
-var guestOSTypeConfigs = map[string]guestOSTypeConfig{
- guestexec.UnixOSType: {
- executeCommand: "{{if .Sudo}}sudo {{end}}chef-solo --no-color -c {{.ConfigPath}} -j {{.JsonPath}}",
- installCommand: "curl -L https://omnitruck.chef.io/install.sh | {{if .Sudo}}sudo {{end}}bash -s --{{if .Version}} -v {{.Version}}{{end}}",
- stagingDir: "/tmp/packer-chef-solo",
- },
- guestexec.WindowsOSType: {
- executeCommand: "c:/opscode/chef/bin/chef-solo.bat --no-color -c {{.ConfigPath}} -j {{.JsonPath}}",
- installCommand: "powershell.exe -Command \". { iwr -useb https://omnitruck.chef.io/install.ps1 } | iex; Install-Project{{if .Version}} -version {{.Version}}{{end}}\"",
- stagingDir: "C:/Windows/Temp/packer-chef-solo",
- },
-}
-
-type Config struct {
- common.PackerConfig `mapstructure:",squash"`
-
- ChefEnvironment string `mapstructure:"chef_environment"`
- ChefLicense string `mapstructure:"chef_license"`
- ConfigTemplate string `mapstructure:"config_template"`
- CookbookPaths []string `mapstructure:"cookbook_paths"`
- RolesPath string `mapstructure:"roles_path"`
- DataBagsPath string `mapstructure:"data_bags_path"`
- EncryptedDataBagSecretPath string `mapstructure:"encrypted_data_bag_secret_path"`
- EnvironmentsPath string `mapstructure:"environments_path"`
- ExecuteCommand string `mapstructure:"execute_command"`
- InstallCommand string `mapstructure:"install_command"`
- RemoteCookbookPaths []string `mapstructure:"remote_cookbook_paths"`
- // 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"`
- StagingDir string `mapstructure:"staging_directory"`
- GuestOSType string `mapstructure:"guest_os_type"`
- Version string `mapstructure:"version"`
-
- ctx interpolate.Context
-}
-
-type Provisioner struct {
- config Config
- guestOSTypeConfig guestOSTypeConfig
- guestCommands *guestexec.GuestCommands
-}
-
-type ConfigTemplate struct {
- CookbookPaths string
- DataBagsPath string
- EncryptedDataBagSecretPath string
- RolesPath string
- EnvironmentsPath string
- ChefEnvironment string
- ChefLicense string
-
- // Templates don't support boolean statements until Go 1.2. In the
- // mean time, we do this.
- // TODO(mitchellh): Remove when Go 1.2 is released
- HasDataBagsPath bool
- HasEncryptedDataBagSecretPath bool
- HasRolesPath bool
- HasEnvironmentsPath bool
-}
-
-type ExecuteTemplate struct {
- ConfigPath string
- JsonPath string
- Sudo bool
-}
-
-type InstallChefTemplate struct {
- Sudo bool
- Version string
-}
-
-func (p *Provisioner) ConfigSpec() hcldec.ObjectSpec { return p.config.FlatMapstructure().HCL2Spec() }
-
-func (p *Provisioner) Prepare(raws ...interface{}) error {
- err := config.Decode(&p.config, &config.DecodeOpts{
- PluginType: "chef-solo",
- Interpolate: true,
- InterpolateContext: &p.config.ctx,
- InterpolateFilter: &interpolate.RenderFilter{
- Exclude: []string{
- "execute_command",
- "install_command",
- },
- },
- }, raws...)
- if err != nil {
- 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
- }
- p.config.GuestOSType = strings.ToLower(p.config.GuestOSType)
-
- var ok bool
- p.guestOSTypeConfig, ok = guestOSTypeConfigs[p.config.GuestOSType]
- if !ok {
- return fmt.Errorf("Invalid guest_os_type: \"%s\"", p.config.GuestOSType)
- }
-
- p.guestCommands, err = guestexec.NewGuestCommands(p.config.GuestOSType, !p.config.PreventSudo)
- if err != nil {
- return fmt.Errorf("Invalid guest_os_type: \"%s\"", p.config.GuestOSType)
- }
-
- if p.config.ExecuteCommand == "" {
- p.config.ExecuteCommand = p.guestOSTypeConfig.executeCommand
- }
-
- if p.config.InstallCommand == "" {
- p.config.InstallCommand = p.guestOSTypeConfig.installCommand
- }
-
- if p.config.RunList == nil {
- p.config.RunList = make([]string, 0)
- }
-
- if p.config.StagingDir == "" {
- p.config.StagingDir = p.guestOSTypeConfig.stagingDir
- }
-
- if p.config.SkipInstall == false && p.config.InstallCommand == p.guestOSTypeConfig.installCommand {
- if p.config.ChefLicense == "" {
- p.config.ChefLicense = "accept-silent"
- }
- }
-
- var errs *packersdk.MultiError
- if p.config.ConfigTemplate != "" {
- fi, err := os.Stat(p.config.ConfigTemplate)
- if err != nil {
- errs = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("Bad config template path: %s", err))
- } else if fi.IsDir() {
- errs = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("Config template path must be a file: %s", err))
- }
- }
-
- for _, path := range p.config.CookbookPaths {
- pFileInfo, err := os.Stat(path)
-
- if err != nil || !pFileInfo.IsDir() {
- errs = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("Bad cookbook path '%s': %s", path, err))
- }
- }
-
- if p.config.RolesPath != "" {
- pFileInfo, err := os.Stat(p.config.RolesPath)
-
- if err != nil || !pFileInfo.IsDir() {
- errs = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("Bad roles path '%s': %s", p.config.RolesPath, err))
- }
- }
-
- if p.config.DataBagsPath != "" {
- pFileInfo, err := os.Stat(p.config.DataBagsPath)
-
- if err != nil || !pFileInfo.IsDir() {
- errs = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("Bad data bags path '%s': %s", p.config.DataBagsPath, err))
- }
- }
-
- if p.config.EncryptedDataBagSecretPath != "" {
- pFileInfo, err := os.Stat(p.config.EncryptedDataBagSecretPath)
-
- if err != nil || pFileInfo.IsDir() {
- errs = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("Bad encrypted data bag secret '%s': %s", p.config.EncryptedDataBagSecretPath, err))
- }
- }
-
- if p.config.EnvironmentsPath != "" {
- pFileInfo, err := os.Stat(p.config.EnvironmentsPath)
-
- if err != nil || !pFileInfo.IsDir() {
- errs = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("Bad environments path '%s': %s", p.config.EnvironmentsPath, err))
- }
- }
-
- jsonValid := true
- for k, v := range p.config.Json {
- p.config.Json[k], err = p.deepJsonFix(k, v)
- if err != nil {
- errs = packersdk.MultiErrorAppend(
- 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 = packersdk.MultiErrorAppend(
- errs, fmt.Errorf("Error processing user variables in JSON: %s", err))
- }
- }
-
- if errs != nil && len(errs.Errors) > 0 {
- return errs
- }
-
- return nil
-}
-
-func (p *Provisioner) Provision(ctx context.Context, ui packersdk.Ui, comm packersdk.Communicator, _ map[string]interface{}) error {
- ui.Say("Provisioning with chef-solo")
-
- if !p.config.SkipInstall {
- if err := p.installChef(ui, comm, p.config.Version); err != nil {
- return fmt.Errorf("Error installing Chef: %s", err)
- }
- }
-
- if err := p.createDir(ui, comm, p.config.StagingDir); err != nil {
- return fmt.Errorf("Error creating staging directory: %s", err)
- }
-
- cookbookPaths := make([]string, 0, len(p.config.CookbookPaths))
- for i, path := range p.config.CookbookPaths {
- targetPath := fmt.Sprintf("%s/cookbooks-%d", p.config.StagingDir, i)
- if err := p.uploadDirectory(ui, comm, targetPath, path); err != nil {
- return fmt.Errorf("Error uploading cookbooks: %s", err)
- }
-
- cookbookPaths = append(cookbookPaths, targetPath)
- }
-
- rolesPath := ""
- if p.config.RolesPath != "" {
- rolesPath = fmt.Sprintf("%s/roles", p.config.StagingDir)
- if err := p.uploadDirectory(ui, comm, rolesPath, p.config.RolesPath); err != nil {
- return fmt.Errorf("Error uploading roles: %s", err)
- }
- }
-
- dataBagsPath := ""
- if p.config.DataBagsPath != "" {
- dataBagsPath = fmt.Sprintf("%s/data_bags", p.config.StagingDir)
- if err := p.uploadDirectory(ui, comm, dataBagsPath, p.config.DataBagsPath); err != nil {
- return fmt.Errorf("Error uploading data bags: %s", err)
- }
- }
-
- encryptedDataBagSecretPath := ""
- if p.config.EncryptedDataBagSecretPath != "" {
- encryptedDataBagSecretPath = fmt.Sprintf("%s/encrypted_data_bag_secret", p.config.StagingDir)
- if err := p.uploadFile(ui, comm, encryptedDataBagSecretPath, p.config.EncryptedDataBagSecretPath); err != nil {
- return fmt.Errorf("Error uploading encrypted data bag secret: %s", err)
- }
- }
-
- environmentsPath := ""
- if p.config.EnvironmentsPath != "" {
- environmentsPath = fmt.Sprintf("%s/environments", p.config.StagingDir)
- if err := p.uploadDirectory(ui, comm, environmentsPath, p.config.EnvironmentsPath); err != nil {
- return fmt.Errorf("Error uploading environments: %s", err)
- }
- }
-
- configPath, err := p.createConfig(ui, comm, cookbookPaths, rolesPath, dataBagsPath, encryptedDataBagSecretPath, environmentsPath, p.config.ChefEnvironment, p.config.ChefLicense)
- if err != nil {
- return fmt.Errorf("Error creating Chef config file: %s", err)
- }
-
- jsonPath, err := p.createJson(ui, comm)
- if err != nil {
- return fmt.Errorf("Error creating JSON attributes: %s", err)
- }
-
- if err := p.executeChef(ui, comm, configPath, jsonPath); err != nil {
- return fmt.Errorf("Error executing Chef: %s", err)
- }
-
- return nil
-}
-
-func (p *Provisioner) uploadDirectory(ui packersdk.Ui, comm packersdk.Communicator, dst string, src string) error {
- if err := p.createDir(ui, comm, dst); err != nil {
- return err
- }
-
- // Make sure there is a trailing "/" so that the directory isn't
- // created on the other side.
- if src[len(src)-1] != '/' {
- src = src + "/"
- }
-
- return comm.UploadDir(dst, src, nil)
-}
-
-func (p *Provisioner) uploadFile(ui packersdk.Ui, comm packersdk.Communicator, dst string, src string) error {
- f, err := os.Open(src)
- if err != nil {
- return err
- }
- defer f.Close()
-
- return comm.Upload(dst, f, nil)
-}
-
-func (p *Provisioner) createConfig(ui packersdk.Ui, comm packersdk.Communicator, localCookbooks []string, rolesPath string, dataBagsPath string, encryptedDataBagSecretPath string, environmentsPath string, chefEnvironment string, chefLicense string) (string, error) {
- ui.Message("Creating configuration file 'solo.rb'")
-
- cookbook_paths := make([]string, len(p.config.RemoteCookbookPaths)+len(localCookbooks))
- for i, path := range p.config.RemoteCookbookPaths {
- cookbook_paths[i] = fmt.Sprintf(`"%s"`, path)
- }
-
- for i, path := range localCookbooks {
- i = len(p.config.RemoteCookbookPaths) + i
- cookbook_paths[i] = fmt.Sprintf(`"%s"`, path)
- }
-
- // Read the template
- tpl := DefaultConfigTemplate
- if p.config.ConfigTemplate != "" {
- f, err := os.Open(p.config.ConfigTemplate)
- if err != nil {
- return "", err
- }
- defer f.Close()
-
- tplBytes, err := ioutil.ReadAll(f)
- if err != nil {
- return "", err
- }
-
- tpl = string(tplBytes)
- }
-
- p.config.ctx.Data = &ConfigTemplate{
- CookbookPaths: strings.Join(cookbook_paths, ","),
- RolesPath: rolesPath,
- DataBagsPath: dataBagsPath,
- EncryptedDataBagSecretPath: encryptedDataBagSecretPath,
- EnvironmentsPath: environmentsPath,
- HasRolesPath: rolesPath != "",
- HasDataBagsPath: dataBagsPath != "",
- HasEncryptedDataBagSecretPath: encryptedDataBagSecretPath != "",
- HasEnvironmentsPath: environmentsPath != "",
- ChefEnvironment: chefEnvironment,
- ChefLicense: chefLicense,
- }
- configString, err := interpolate.Render(tpl, &p.config.ctx)
- if err != nil {
- return "", err
- }
-
- remotePath := filepath.ToSlash(filepath.Join(p.config.StagingDir, "solo.rb"))
- if err := comm.Upload(remotePath, bytes.NewReader([]byte(configString)), nil); err != nil {
- return "", err
- }
-
- return remotePath, nil
-}
-
-func (p *Provisioner) createJson(ui packersdk.Ui, comm packersdk.Communicator) (string, error) {
- 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
- }
-
- jsonBytes, err := json.MarshalIndent(jsonData, "", " ")
- if err != nil {
- return "", err
- }
-
- // Upload the bytes
- remotePath := filepath.ToSlash(filepath.Join(p.config.StagingDir, "node.json"))
- if err := comm.Upload(remotePath, bytes.NewReader(jsonBytes), nil); err != nil {
- return "", err
- }
-
- return remotePath, nil
-}
-
-func (p *Provisioner) createDir(ui packersdk.Ui, comm packersdk.Communicator, dir string) error {
- ui.Message(fmt.Sprintf("Creating directory: %s", dir))
- ctx := context.TODO()
-
- cmd := &packersdk.RemoteCmd{Command: p.guestCommands.CreateDir(dir)}
- if err := cmd.RunWithUi(ctx, 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
- cmd = &packersdk.RemoteCmd{Command: p.guestCommands.Chmod(dir, "0777")}
- if err := cmd.RunWithUi(ctx, comm, ui); err != nil {
- return err
- }
- if cmd.ExitStatus() != 0 {
- return fmt.Errorf("Non-zero exit status. See output above for more info.")
- }
-
- return nil
-}
-
-func (p *Provisioner) executeChef(ui packersdk.Ui, comm packersdk.Communicator, config string, json string) error {
- p.config.ctx.Data = &ExecuteTemplate{
- ConfigPath: config,
- JsonPath: json,
- Sudo: !p.config.PreventSudo,
- }
- command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx)
- if err != nil {
- return err
- }
-
- ui.Message(fmt.Sprintf("Executing Chef: %s", command))
-
- cmd := &packersdk.RemoteCmd{
- Command: command,
- }
- ctx := context.TODO()
- if err := cmd.RunWithUi(ctx, comm, ui); err != nil {
- return err
- }
-
- if cmd.ExitStatus() != 0 {
- return fmt.Errorf("Non-zero exit status: %d", cmd.ExitStatus())
- }
-
- return nil
-}
-
-func (p *Provisioner) installChef(ui packersdk.Ui, comm packersdk.Communicator, version string) error {
- ui.Message("Installing Chef...")
- ctx := context.TODO()
-
- p.config.ctx.Data = &InstallChefTemplate{
- Sudo: !p.config.PreventSudo,
- Version: version,
- }
- command, err := interpolate.Render(p.config.InstallCommand, &p.config.ctx)
- if err != nil {
- return err
- }
-
- cmd := &packersdk.RemoteCmd{Command: command}
- if err := cmd.RunWithUi(ctx, comm, ui); err != nil {
- return err
- }
-
- if cmd.ExitStatus() != 0 {
- return fmt.Errorf(
- "Install script exited with non-zero exit status %d", cmd.ExitStatus())
- }
-
- 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 []uint8:
- return string(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
- default:
- return current, 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.ctx.UserVariables {
- originalUserVars[k] = v
- }
-
- // Make sure we reset them no matter what
- defer func() {
- p.config.ctx.UserVariables = originalUserVars
- }()
-
- // Make the current user variables JSON string safe.
- for k, v := range p.config.ctx.UserVariables {
- v = strings.Replace(v, `\`, `\\`, -1)
- v = strings.Replace(v, `"`, `\"`, -1)
- p.config.ctx.UserVariables[k] = v
- }
-
- // Process the bytes with the template processor
- p.config.ctx.Data = nil
- jsonBytesProcessed, err := interpolate.Render(string(jsonBytes), &p.config.ctx)
- 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
-}
-
-var DefaultConfigTemplate = `
-chef_license "{{.ChefLicense}}"
-cookbook_path [{{.CookbookPaths}}]
-{{if .HasRolesPath}}
-role_path "{{.RolesPath}}"
-{{end}}
-{{if .HasDataBagsPath}}
-data_bag_path "{{.DataBagsPath}}"
-{{end}}
-{{if .HasEncryptedDataBagSecretPath}}
-encrypted_data_bag_secret "{{.EncryptedDataBagSecretPath}}"
-{{end}}
-{{if .HasEnvironmentsPath}}
-environment_path "{{.EnvironmentsPath}}"
-environment "{{.ChefEnvironment}}"
-{{end}}
-`
diff --git a/provisioner/chef-solo/provisioner.hcl2spec.go b/provisioner/chef-solo/provisioner.hcl2spec.go
deleted file mode 100644
index bf8dd12cf..000000000
--- a/provisioner/chef-solo/provisioner.hcl2spec.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
-
-package chefsolo
-
-import (
- "github.com/hashicorp/hcl/v2/hcldec"
- "github.com/zclconf/go-cty/cty"
-)
-
-// FlatConfig is an auto-generated flat version of Config.
-// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
-type FlatConfig struct {
- PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
- PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
- PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"`
- PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
- PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
- PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
- PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"`
- PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"`
- ChefEnvironment *string `mapstructure:"chef_environment" cty:"chef_environment" hcl:"chef_environment"`
- ChefLicense *string `mapstructure:"chef_license" cty:"chef_license" hcl:"chef_license"`
- ConfigTemplate *string `mapstructure:"config_template" cty:"config_template" hcl:"config_template"`
- CookbookPaths []string `mapstructure:"cookbook_paths" cty:"cookbook_paths" hcl:"cookbook_paths"`
- RolesPath *string `mapstructure:"roles_path" cty:"roles_path" hcl:"roles_path"`
- DataBagsPath *string `mapstructure:"data_bags_path" cty:"data_bags_path" hcl:"data_bags_path"`
- EncryptedDataBagSecretPath *string `mapstructure:"encrypted_data_bag_secret_path" cty:"encrypted_data_bag_secret_path" hcl:"encrypted_data_bag_secret_path"`
- EnvironmentsPath *string `mapstructure:"environments_path" cty:"environments_path" hcl:"environments_path"`
- 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"`
- 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"`
- StagingDir *string `mapstructure:"staging_directory" cty:"staging_directory" hcl:"staging_directory"`
- GuestOSType *string `mapstructure:"guest_os_type" cty:"guest_os_type" hcl:"guest_os_type"`
- Version *string `mapstructure:"version" cty:"version" hcl:"version"`
-}
-
-// FlatMapstructure returns a new FlatConfig.
-// FlatConfig is an auto-generated flat version of Config.
-// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
-func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
- return new(FlatConfig)
-}
-
-// HCL2Spec returns the hcl spec of a Config.
-// This spec is used by HCL to read the fields of Config.
-// The decoded values from this spec will then be applied to a FlatConfig.
-func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
- s := map[string]hcldec.Spec{
- "packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
- "packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
- "packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false},
- "packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
- "packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
- "packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
- "packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false},
- "packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
- "chef_environment": &hcldec.AttrSpec{Name: "chef_environment", Type: cty.String, Required: false},
- "chef_license": &hcldec.AttrSpec{Name: "chef_license", Type: cty.String, Required: false},
- "config_template": &hcldec.AttrSpec{Name: "config_template", Type: cty.String, Required: false},
- "cookbook_paths": &hcldec.AttrSpec{Name: "cookbook_paths", Type: cty.List(cty.String), Required: false},
- "roles_path": &hcldec.AttrSpec{Name: "roles_path", Type: cty.String, Required: false},
- "data_bags_path": &hcldec.AttrSpec{Name: "data_bags_path", Type: cty.String, Required: false},
- "encrypted_data_bag_secret_path": &hcldec.AttrSpec{Name: "encrypted_data_bag_secret_path", Type: cty.String, Required: false},
- "environments_path": &hcldec.AttrSpec{Name: "environments_path", Type: cty.String, Required: false},
- "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_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},
- "staging_directory": &hcldec.AttrSpec{Name: "staging_directory", Type: cty.String, Required: false},
- "guest_os_type": &hcldec.AttrSpec{Name: "guest_os_type", Type: cty.String, Required: false},
- "version": &hcldec.AttrSpec{Name: "version", Type: cty.String, Required: false},
- }
- return s
-}
diff --git a/provisioner/chef-solo/provisioner_test.go b/provisioner/chef-solo/provisioner_test.go
deleted file mode 100644
index f1b0aef41..000000000
--- a/provisioner/chef-solo/provisioner_test.go
+++ /dev/null
@@ -1,390 +0,0 @@
-package chefsolo
-
-import (
- "io/ioutil"
- "os"
- "testing"
-
- "github.com/hashicorp/packer-plugin-sdk/common"
- packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
-)
-
-func testConfig() map[string]interface{} {
- return map[string]interface{}{}
-}
-
-func TestProvisioner_Impl(t *testing.T) {
- var raw interface{}
- raw = &Provisioner{}
- if _, ok := raw.(packersdk.Provisioner); !ok {
- t.Fatalf("must be a Provisioner")
- }
-}
-
-func TestProvisionerPrepare_chefEnvironment(t *testing.T) {
- var p Provisioner
-
- config := testConfig()
- config["chef_environment"] = "some-env"
-
- err := p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if p.config.ChefEnvironment != "some-env" {
- t.Fatalf("unexpected: %#v", p.config.ChefEnvironment)
- }
-}
-func TestProvisionerPrepare_chefLicense(t *testing.T) {
- var p Provisioner
-
- // Test not set
- config := testConfig()
- err := p.Prepare(config)
- if err != nil {
- t.Fatal("should error")
- }
-
- if p.config.ChefLicense != "accept-silent" {
- t.Fatalf("unexpected: %#v", p.config.ChefLicense)
- }
-
- // Test set
- config = testConfig()
- config["chef_license"] = "accept"
- p = Provisioner{}
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if p.config.ChefLicense != "accept" {
- t.Fatalf("unexpected: %#v", p.config.ChefLicense)
- }
-
- // Test set skipInstall true
- config = testConfig()
- config["skip_install"] = true
- p = Provisioner{}
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if p.config.ChefLicense != "" {
- t.Fatalf("unexpected: %#v", "empty string")
- }
-
- // Test set installCommand true
- config = testConfig()
- config["install_command"] = "install chef"
- p = Provisioner{}
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if p.config.ChefLicense != "" {
- t.Fatalf("unexpected: %#v", "empty string")
- }
-}
-
-func TestProvisionerPrepare_configTemplate(t *testing.T) {
- var err error
- var p Provisioner
-
- // Test no config template
- config := testConfig()
- delete(config, "config_template")
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- // Test with a file
- tf, err := ioutil.TempFile("", "packer")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer os.Remove(tf.Name())
-
- config = testConfig()
- config["config_template"] = tf.Name()
- p = Provisioner{}
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- // Test with a directory
- td, err := ioutil.TempDir("", "packer")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer os.RemoveAll(td)
-
- config = testConfig()
- config["config_template"] = td
- p = Provisioner{}
- err = p.Prepare(config)
- if err == nil {
- t.Fatal("should have err")
- }
-}
-
-func TestProvisionerPrepare_cookbookPaths(t *testing.T) {
- var p Provisioner
-
- path1, err := ioutil.TempDir("", "cookbooks_one")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- path2, err := ioutil.TempDir("", "cookbooks_two")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- rolesPath, err := ioutil.TempDir("", "roles")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- dataBagsPath, err := ioutil.TempDir("", "data_bags")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- defer os.Remove(path1)
- defer os.Remove(path2)
- defer os.Remove(rolesPath)
- defer os.Remove(dataBagsPath)
-
- config := testConfig()
- config["cookbook_paths"] = []string{path1, path2}
- config["roles_path"] = rolesPath
- config["data_bags_path"] = dataBagsPath
-
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if len(p.config.CookbookPaths) != 2 {
- t.Fatalf("unexpected: %#v", p.config.CookbookPaths)
- }
-
- if p.config.CookbookPaths[0] != path1 || p.config.CookbookPaths[1] != path2 {
- t.Fatalf("unexpected: %#v", p.config.CookbookPaths)
- }
-
- if p.config.RolesPath != rolesPath {
- t.Fatalf("unexpected: %#v", p.config.RolesPath)
- }
-
- if p.config.DataBagsPath != dataBagsPath {
- t.Fatalf("unexpected: %#v", p.config.DataBagsPath)
- }
-}
-
-func TestProvisionerPrepare_dataBagsPath(t *testing.T) {
- var p Provisioner
-
- dataBagsPath, err := ioutil.TempDir("", "data_bags")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer os.Remove(dataBagsPath)
-
- config := testConfig()
- config["data_bags_path"] = dataBagsPath
-
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if p.config.DataBagsPath != dataBagsPath {
- t.Fatalf("unexpected: %#v", p.config.DataBagsPath)
- }
-}
-
-func TestProvisionerPrepare_encryptedDataBagSecretPath(t *testing.T) {
- var err error
- var p Provisioner
-
- // Test no config template
- config := testConfig()
- delete(config, "encrypted_data_bag_secret_path")
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- // Test with a file
- tf, err := ioutil.TempFile("", "packer")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer os.Remove(tf.Name())
-
- config = testConfig()
- config["encrypted_data_bag_secret_path"] = tf.Name()
- p = Provisioner{}
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- // Test with a directory
- td, err := ioutil.TempDir("", "packer")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer os.RemoveAll(td)
-
- config = testConfig()
- config["encrypted_data_bag_secret_path"] = td
- p = Provisioner{}
- err = p.Prepare(config)
- if err == nil {
- t.Fatal("should have err")
- }
-}
-
-func TestProvisionerPrepare_environmentsPath(t *testing.T) {
- var p Provisioner
-
- environmentsPath, err := ioutil.TempDir("", "environments")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer os.Remove(environmentsPath)
-
- config := testConfig()
- config["environments_path"] = environmentsPath
-
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if p.config.EnvironmentsPath != environmentsPath {
- t.Fatalf("unexpected: %#v", p.config.EnvironmentsPath)
- }
-}
-
-func TestProvisionerPrepare_rolesPath(t *testing.T) {
- var p Provisioner
-
- rolesPath, err := ioutil.TempDir("", "roles")
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer os.Remove(rolesPath)
-
- config := testConfig()
- config["roles_path"] = rolesPath
-
- err = p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if p.config.RolesPath != rolesPath {
- t.Fatalf("unexpected: %#v", p.config.RolesPath)
- }
-}
-
-func TestProvisionerPrepare_json(t *testing.T) {
- config := testConfig()
- config["json"] = map[string]interface{}{
- "foo": "{{ user `foo` }}",
- }
-
- config[common.UserVariablesConfigKey] = map[string]string{
- "foo": `"bar\baz"`,
- }
-
- var p Provisioner
- err := p.Prepare(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- if p.config.Json["foo"] != `"bar\baz"` {
- 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": []uint8("baz"),
- },
-
- "bar": []interface{}{
- "foo",
-
- map[interface{}]interface{}{
- "bar": "baz",
- },
- },
-
- "bFalse": false,
- "bTrue": true,
- "bNil": nil,
- "bStr": []uint8("bar"),
-
- "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"])
- }
-}
-
-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"])
- }
-}
diff --git a/provisioner/chef-solo/version/version.go b/provisioner/chef-solo/version/version.go
deleted file mode 100644
index 44d97133e..000000000
--- a/provisioner/chef-solo/version/version.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package version
-
-import (
- "github.com/hashicorp/packer-plugin-sdk/version"
- packerVersion "github.com/hashicorp/packer/version"
-)
-
-var ChefSoloPluginVersion *version.PluginVersion
-
-func init() {
- ChefSoloPluginVersion = version.InitializePluginVersion(
- packerVersion.Version, packerVersion.VersionPrerelease)
-}
diff --git a/website/content/docs/provisioners/chef-client.mdx b/website/content/docs/provisioners/chef-client.mdx
deleted file mode 100644
index 91f96f467..000000000
--- a/website/content/docs/provisioners/chef-client.mdx
+++ /dev/null
@@ -1,430 +0,0 @@
----
-description: >
- The chef-client Packer provisioner installs and configures software on
- machines
-
- built by Packer using chef-client. Packer configures a Chef client to talk to
- a
-
- remote Chef Server to provision the machine.
-page_title: Chef Client - Provisioners
----
-
-# Chef Client Provisioner
-
-@include 'provisioners/unmaintained-plugin.mdx'
-
-Type: `chef-client`
-
-The Chef Client Packer provisioner installs and configures software on machines
-built by Packer using [chef-client](https://docs.chef.io/chef_client.html).
-Packer configures a Chef client to talk to a remote Chef Server to provision
-the machine.
-
-The provisioner will even install Chef onto your machine if it isn't already
-installed, using the official Chef installers provided by Chef.
-
-## Basic Example
-
-The example below is fully functional. It will install Chef onto the remote
-machine and run Chef client.
-
-```json
-{
- "type": "chef-client",
- "server_url": "https://mychefserver.com/"
-}
-```
-
-Note: to properly clean up the Chef node and client the machine on which packer
-is running must have knife on the path and configured globally, i.e,
-`~/.chef/knife.rb` must be present and configured for the target chef server
-
-## Configuration Reference
-
-The reference of available configuration options is listed below. No
-configuration is actually required.
-
-- `chef_environment` (string) - The name of the chef_environment sent to the
- Chef server. By default this is empty and will not use an environment.
-
-- `chef_license` (string) - As of Chef v15, Chef requires users to accept a
- license. Defaults to `accept-silent` when `skip_install` is false and
- `install_command` is unset. Possible values are `accept`,
- `accept-silent` and `accept-no-persist`. For details see [Accepting the
- Chef License](https://docs.chef.io/chef_license_accept.html).
-
- This is a [template engine](/docs/templates/legacy_json_templates/engine.html). Therefore, you
- may use user variables and template functions in this field.
-
-- `config_template` (string) - Path to a template that will be used for the
- Chef configuration file. By default Packer only sets configuration it needs
- to match the settings set in the provisioner configuration. If you need to
- set configurations that the Packer provisioner doesn't support, then you
- should use a custom configuration template. See the dedicated "Chef
- Configuration" section below for more details.
-
-- `elevated_user` and `elevated_password` (string) - If specified, Chef will
- be run with elevated privileges using the given Windows user. See the
- [powershell](/docs/provisioners/powershell) provisioner for the full
- details.
-
-- `encrypted_data_bag_secret_path` (string) - The path to the file containing
- the secret for encrypted data bags. By default, this is empty, so no secret
- will be available.
-
-- `execute_command` (string) - The command used to execute Chef. This has
- various [configuration template variables](/docs/templates/legacy_json_templates/engine)
- available. See below for more information.
-
-- `guest_os_type` (string) - The target guest OS type, either "unix" or
- "windows". Setting this to "windows" will cause the provisioner to use
- Windows friendly paths and commands. By default, this is "unix".
-
-- `install_command` (string) - The command used to install Chef. This has
- 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.
-
-- `knife_command` (string) - The command used to run Knife during node
- clean-up. This has various [configuration template
- variables](/docs/templates/legacy_json_templates/engine) available. See below for more
- information.
-
-- `node_name` (string) - The name of the node to register with the Chef
- Server. This is optional and by default is `packer-{{uuid}}`.
-
-- `policy_group` (string) - The name of a policy group that exists on the
- Chef server. `policy_name` must also be specified.
-
-- `policy_name` (string) - The name of a policy, as identified by the name
- setting in a `Policyfile.rb` file. `policy_group` must also be specified.
-
-- `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
- windows.
-
-- `run_list` (array of strings) - The [run
- list](https://docs.chef.io/run_lists) for Chef.
- By default this is empty, and will use the run list sent down by the Chef
- Server.
-
-- `server_url` (string) - The URL to the Chef server. This is required.
-
-- `skip_clean_client` (boolean) - If true, Packer won't remove the client
- from the Chef server after it is done running. By default, this is false.
-
-- `skip_clean_node` (boolean) - If true, Packer won't remove the node from
- the Chef server after it is done running. By default, this is false.
-
-- `skip_clean_staging_directory` (boolean) - If true, Packer won't remove the
- Chef staging directory from the machine after it is done running. By
- default, this is false.
-
-- `skip_install` (boolean) - If true, Chef will not automatically be
- installed on the machine using the Chef omnibus installers.
-
-- `ssl_verify_mode` (string) - Set to "verify_none" to skip validation of
- SSL certificates. If not set, this defaults to "verify_peer" which
- validates all SSL certifications.
-
-- `trusted_certs_dir` (string) - This is a directory that contains additional
- SSL certificates to trust. Any certificates in this directory will be added
- to whatever CA bundle ruby is using. Use this to add self-signed certs for
- your Chef Server or local HTTP file servers.
-
-- `staging_directory` (string) - This is the directory where all the
- configuration of Chef by Packer will be placed. By default this is
- `/tmp/packer-chef-client` when guest_os_type unix and
- `$env:TEMP/packer-chef-client` when windows. This directory doesn't need to
- exist but must have proper permissions so that the user that Packer uses is
- able to create directories and write into this folder. By default the
- provisioner will create and chmod 0777 this directory.
-
-- `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 not
- set, this won't be set in the configuration and the default that Chef uses
- will be used.
-
-- `validation_key_path` (string) - Path to the validation key for
- communicating with the Chef Server. This will be uploaded to the remote
- machine. If this is NOT set, then it is your responsibility via other means
- (shell provisioner, etc.) to get a validation key to where Chef expects it.
-
-- `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'
-
-## Chef Configuration
-
-By default, Packer uses a simple Chef configuration file in order to set the
-options specified for the provisioner. But Chef is a complex tool that supports
-many configuration options. Packer allows you to specify a custom configuration
-template if you'd like to set custom configurations.
-
-The default value for the configuration template is:
-
-```liquid
-log_level :info
-log_location STDOUT
-chef_server_url "{{.ServerUrl}}"
-client_key "{{.ClientKey}}"
-chef_license "{{.ChefLicense}}"
-{{if ne .EncryptedDataBagSecretPath ""}}
-encrypted_data_bag_secret "{{.EncryptedDataBagSecretPath}}"
-{{end}}
-{{if ne .ValidationClientName ""}}
-validation_client_name "{{.ValidationClientName}}"
-{{else}}
-validation_client_name "chef-validator"
-{{end}}
-{{if ne .ValidationKeyPath ""}}
-validation_key "{{.ValidationKeyPath}}"
-{{end}}
-node_name "{{.NodeName}}"
-{{if ne .ChefEnvironment ""}}
-environment "{{.ChefEnvironment}}"
-{{end}}
-{{if ne .PolicyGroup ""}}
-policy_group "{{.PolicyGroup}}"
-{{end}}
-{{if ne .PolicyName ""}}
-policy_name "{{.PolicyName}}"
-{{end}}
-{{if ne .SslVerifyMode ""}}
-ssl_verify_mode :{{.SslVerifyMode}}
-{{end}}
-{{if ne .TrustedCertsDir ""}}
-trusted_certs_dir :{{.TrustedCertsDir}}
-{{end}}
-```
-
-This template is a [configuration template](/docs/templates/legacy_json_templates/engine) and
-has a set of variables available to use:
-
-- `ChefEnvironment` - The Chef environment name.
-- `ChefLicense` - The Chef license acceptance value.
-- `EncryptedDataBagSecretPath` - The path to the secret key file to decrypt
- encrypted data bags.
-- `NodeName` - The node name set in the configuration.
-- `ServerUrl` - The URL of the Chef Server set in the configuration.
-- `SslVerifyMode` - Whether Chef SSL verify mode is on or off.
-- `TrustedCertsDir` - Path to dir with trusted certificates.
-- `ValidationClientName` - The name of the client used for validation.
-- `ValidationKeyPath` - Path to the validation key, if it is set.
-
-## Execute Command
-
-By default, Packer uses the following command (broken across multiple lines for
-readability) to execute Chef:
-
-```liquid
-{{if .Sudo}}sudo {{end}}chef-client \
- --no-color \
- -c {{.ConfigPath}} \
- -j {{.JsonPath}}
-```
-
-When guest_os_type is set to "windows", Packer uses the following command to
-execute Chef. The full path to Chef is required because the PATH environment
-variable changes don't immediately propagate to running processes.
-
-```liquid
-c:/opscode/chef/bin/chef-client.bat \
- --no-color \
- -c {{.ConfigPath}} \
- -j {{.JsonPath}}
-```
-
-This command can be customized using the `execute_command` configuration. As
-you can see from the default value above, the value of this configuration can
-contain various template variables, defined below:
-
-- `ConfigPath` - The path to the Chef configuration file.
-- `JsonPath` - The path to the JSON attributes file for the node.
-- `Sudo` - A boolean of whether to `sudo` the command or not, depending on
- the value of the `prevent_sudo` configuration.
-
-## Install Command
-
-By default, Packer uses the following command (broken across multiple lines for
-readability) to install Chef. This command can be customized if you want to
-install Chef in another way.
-
-```text
-curl -L https://omnitruck.chef.io/chef/install.sh | \
- {{if .Sudo}}sudo{{end}} bash
-```
-
-When guest_os_type is set to "windows", Packer uses the following command to
-install the latest version of Chef:
-
-```text
-powershell.exe -Command "(New-Object System.Net.WebClient).DownloadFile('http://chef.io/chef/install.msi', 'C:\\Windows\\Temp\\chef.msi');Start-Process 'msiexec' -ArgumentList '/qb /i C:\\Windows\\Temp\\chef.msi' -NoNewWindow -Wait"
-```
-
-This command can be customized using the `install_command` configuration.
-
-## Knife Command
-
-By default, Packer uses the following command (broken across multiple lines for
-readability) to execute Chef:
-
-```liquid
-{{if .Sudo}}sudo {{end}}knife \
- {{.Args}} \
- {{.Flags}}
-```
-
-When guest_os_type is set to "windows", Packer uses the following command to
-execute Chef. The full path to Chef is required because the PATH environment
-variable changes don't immediately propagate to running processes.
-
-```liquid
-c:/opscode/chef/bin/knife.bat \
- {{.Args}} \
- {{.Flags}}
-```
-
-This command can be customized using the `knife_command` configuration. As you
-can see from the default value above, the value of this configuration can
-contain various template variables, defined below:
-
-- `Args` - The command arguments that are getting passed to the Knife
- command.
-- `Flags` - The command flags that are getting passed to the Knife command..
-- `Sudo` - A boolean of whether to `sudo` the command or not, depending on
- the value of the `prevent_sudo` 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.
-
-## Examples
-
-### Chef Client Local Mode - Simple
-
-The following example shows how to run the `chef-client` provisioner in local
-mode.
-
-**Packer variables**
-
-Set the necessary Packer variables using environment variables or provide a
-[var file](/docs/templates/legacy_json_templates/user-variables).
-
-```json
-"variables": {
- "chef_dir": "/tmp/packer-chef-client"
-}
-```
-
-**Setup the** `chef-client` **provisioner**
-
-Make sure we have the correct directories and permissions for the `chef-client`
-provisioner. You will need to bootstrap the Chef run by providing the necessary
-cookbooks using Berkshelf or some other means.
-
-```json
- "provisioners": [
- ...
- { "type": "shell", "inline": [ "mkdir -p {{user `chef_dir`}}" ] },
- { "type": "file", "source": "./roles", "destination": "{{user `chef_dir`}}" },
- { "type": "file", "source": "./cookbooks", "destination": "{{user `chef_dir`}}" },
- { "type": "file", "source": "./data_bags", "destination": "{{user `chef_dir`}}" },
- { "type": "file", "source": "./environments", "destination": "{{user `chef_dir`}}" },
- { "type": "file", "source": "./scripts/install_chef.sh", "destination": "{{user `chef_dir`}}/install_chef.sh" },
- {
- "type": "chef-client",
- "install_command": "sudo bash {{user `chef_dir`}}/install_chef.sh",
- "server_url": "http://localhost:8889",
- "config_template": "./config/client.rb.template",
- "run_list": [ "role[testing]" ],
- "skip_clean_node": true,
- "skip_clean_client": true
- }
- ...
- ]
-```
-
-And ./config/client.rb.template referenced by the above configuration:
-
-```ruby
-log_level :info
-log_location STDOUT
-local_mode true
-chef_zero.enabled true
-ssl_verify_mode "verify_peer"
-role_path "{{user `chef_dir`}}/roles"
-data_bag_path "{{user `chef_dir`}}/data_bags"
-environment_path "{{user `chef_dir`}}/environments"
-cookbook_path [ "{{user `chef_dir`}}/cookbooks" ]
-```
-
-### Chef Client Local Mode - Passing variables
-
-The following example shows how to run the `chef-client` provisioner in local
-mode, while passing a `run_list` using a variable.
-
-**Local environment variables**
-
- # Machine's Chef directory
- export PACKER_CHEF_DIR=/var/chef-packer
- # Comma separated run_list
- export PACKER_CHEF_RUN_LIST="recipe[apt],recipe[nginx]"
-
-**Packer variables**
-
-Set the necessary Packer variables using environment variables or provide a
-[var file](/docs/templates/legacy_json_templates/user-variables).
-
-```json
-"variables": {
- "chef_dir": "{{env `PACKER_CHEF_DIR`}}",
- "chef_run_list": "{{env `PACKER_CHEF_RUN_LIST`}}",
- "chef_client_config_tpl": "{{env `PACKER_CHEF_CLIENT_CONFIG_TPL`}}",
- "packer_chef_bootstrap_dir": "{{env `PACKER_CHEF_BOOTSTRAP_DIR`}}" ,
- "packer_uid": "{{env `PACKER_UID`}}",
- "packer_gid": "{{env `PACKER_GID`}}"
-}
-```
-
-**Setup the** `chef-client` **provisioner**
-
-Make sure we have the correct directories and permissions for the `chef-client`
-provisioner. You will need to bootstrap the Chef run by providing the necessary
-cookbooks using Berkshelf or some other means.
-
-```json
-({
- "type": "file",
- "source": "{{user `packer_chef_bootstrap_dir`}}",
- "destination": "/tmp/bootstrap"
-},
-{
- "type": "shell",
- "inline": [
- "sudo mkdir -p {{user `chef_dir`}}",
- "sudo mkdir -p /tmp/packer-chef-client",
- "sudo chown {{user `packer_uid`}}.{{user `packer_gid`}} /tmp/packer-chef-client",
- "sudo sh /tmp/bootstrap/bootstrap.sh"
- ]
-},
-{
- "type": "chef-client",
- "server_url": "http://localhost:8889",
- "config_template": "{{user `chef_client_config_tpl`}}/client.rb.tpl",
- "skip_clean_node": true,
- "skip_clean_client": true,
- "run_list": "{{user `chef_run_list`}}"
-})
-```
diff --git a/website/content/docs/provisioners/chef-solo.mdx b/website/content/docs/provisioners/chef-solo.mdx
deleted file mode 100644
index 4ceb48f73..000000000
--- a/website/content/docs/provisioners/chef-solo.mdx
+++ /dev/null
@@ -1,256 +0,0 @@
----
-description: |
- The chef-solo Packer provisioner installs and configures software on machines
- built by Packer using chef-solo. Cookbooks can be uploaded from your local
- machine to the remote machine or remote paths can be used.
-page_title: Chef Solo - Provisioners
----
-
-# Chef Solo Provisioner
-
-@include 'provisioners/unmaintained-plugin.mdx'
-
-Type: `chef-solo`
-
-The Chef solo Packer provisioner installs and configures software on machines
-built by Packer using [chef-solo](https://docs.chef.io/chef_solo.html).
-Cookbooks can be uploaded from your local machine to the remote machine or
-remote paths can be used.
-
-The provisioner will even install Chef onto your machine if it isn't already
-installed, using the official Chef installers provided by Chef Inc.
-
-## Basic Example
-
-The example below is fully functional and expects cookbooks in the "cookbooks"
-directory relative to your working directory.
-
-
-
-
-```hcl
-provisioner "chef-solo" {
- cookbook_paths = ["cookbooks"]
-}
-```
-
-
-
-
-
-```json
-"provisioners":[{
- "type": "chef-solo",
- "cookbook_paths": ["cookbooks"]
-}]
-```
-
-
-
-
-## Configuration Reference
-
-The reference of available configuration options is listed below. No
-configuration is actually required, but at least `run_list` is recommended.
-
-- `chef_environment` (string) - The name of the `chef_environment` sent to
- the Chef server. By default this is empty and will not use an environment
-
-- `chef_license` (string) - As of Chef v15, Chef requires users to accept a
- license. Defaults to `accept-silent` when `skip_install` is false and
- `install_command` is unset. Possible values are `accept`,
- `accept-silent` and `accept-no-persist`. For details see [Accepting the
- Chef License](https://docs.chef.io/chef_license_accept.html).
-
-- `config_template` (string) - Path to a template that will be used for the
- Chef configuration file. By default Packer only sets configuration it needs
- to match the settings set in the provisioner configuration. If you need to
- set configurations that the Packer provisioner doesn't support, then you
- should use a custom configuration template. See the dedicated "Chef
- Configuration" section below for more details.
-
-- `cookbook_paths` (array of strings) - This is an array of paths to
- "cookbooks" directories on your local filesystem. These will be uploaded to
- the remote machine in the directory specified by the `staging_directory`.
- By default, this is empty.
-
-- `data_bags_path` (string) - The path to the "data_bags" directory on your
- local filesystem. These will be uploaded to the remote machine in the
- directory specified by the `staging_directory`. By default, this is empty.
-
-- `encrypted_data_bag_secret_path` (string) - The path to the file containing
- the secret for encrypted data bags. By default, this is empty, so no secret
- will be available.
-
-- `environments_path` (string) - The path to the "environments" directory on
- your local filesystem. These will be uploaded to the remote machine in the
- directory specified by the `staging_directory`. By default, this is empty.
-
-- `execute_command` (string) - The command used to execute Chef. This has
- various [configuration template variables](/docs/templates/legacy_json_templates/engine)
- available. See below for more information.
-
-- `guest_os_type` (string) - The target guest OS type, either "unix" or
- "windows". Setting this to "windows" will cause the provisioner to use
- Windows friendly paths and commands. By default, this is "unix".
-
-- `install_command` (string) - The command used to install Chef. This has
- various [configuration template variables](/docs/templates/legacy_json_templates/engine)
- available. See below for more information.
-
-- `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
- windows.
-
-- `remote_cookbook_paths` (array of strings) - A list of paths on the remote
- machine where cookbooks will already exist. These may exist from a previous
- provisioner or step. If specified, Chef will be configured to look for
- cookbooks here. By default, this is empty.
-
-- `roles_path` (string) - The path to the "roles" directory on your local
- filesystem. These will be uploaded to the remote machine in the directory
- specified by the `staging_directory`. By default, this is empty.
-
-- `run_list` (array of strings) - The [run
- list](https://docs.chef.io/run_lists.html) for Chef. By default this is
- empty.
-
-- `skip_install` (boolean) - If true, Chef will not automatically be
- installed on the machine using the Chef omnibus installers.
-
-- `staging_directory` (string) - This is the directory where all the
- configuration of Chef by Packer will be placed. By default this is
- `/tmp/packer-chef-solo` when guest_os_type unix and
- `$env:TEMP/packer-chef-solo` when windows. This directory doesn't need to
- exist but must have proper permissions so that the user that Packer uses is
- 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.
-
-
-
-
-- `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
- }
- })
-}
-```
-
-
-
-
-
-- `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
- }
- }
-}]
-```
-
-
-
-
-## Chef Configuration
-
-By default, Packer uses a simple Chef configuration file in order to set the
-options specified for the provisioner. But Chef is a complex tool that supports
-many configuration options. Packer allows you to specify a custom configuration
-template if you'd like to set custom configurations.
-
-The default value for the configuration template is:
-
-```liquid
-cookbook_path [{{.CookbookPaths}}]
-```
-
-This template is a [configuration template](/docs/templates/legacy_json_templates/engine) and
-has a set of variables available to use:
-
-- `ChefEnvironment` - The current enabled environment. Only non-empty if the
- environment path is set.
-- `ChefLicense` - The Chef license acceptance value.
-- `CookbookPaths` is the set of cookbook paths ready to embedded directly
- into a Ruby array to configure Chef.
-- `DataBagsPath` is the path to the data bags folder.
-- `EncryptedDataBagSecretPath` - The path to the encrypted data bag secret
-- `EnvironmentsPath` - The path to the environments folder.
-- `RolesPath` - The path to the roles folder.
-
-## Execute Command
-
-By default, Packer uses the following command (broken across multiple lines for
-readability) to execute Chef:
-
-```liquid
-{{if .Sudo}}sudo {{end}}chef-solo \
- --no-color \
- -c {{.ConfigPath}} \
- -j {{.JsonPath}}
-```
-
-When guest_os_type is set to "windows", Packer uses the following command to
-execute Chef. The full path to Chef is required because the PATH environment
-variable changes don't immediately propagate to running processes.
-
-```liquid
-c:/opscode/chef/bin/chef-solo.bat \
- --no-color \
- -c {{.ConfigPath}} \
- -j {{.JsonPath}}
-```
-
-This command can be customized using the `execute_command` configuration. As
-you can see from the default value above, the value of this configuration can
-contain various template variables, defined below:
-
-- `ConfigPath` - The path to the Chef configuration file.
-- `JsonPath` - The path to the JSON attributes file for the node.
-- `Sudo` - A boolean of whether to `sudo` the command or not, depending on
- the value of the `prevent_sudo` configuration.
-
-## Install Command
-
-By default, Packer uses the following command (broken across multiple lines for
-readability) to install Chef. This command can be customized if you want to
-install Chef in another way.
-
-```text
-curl -L https://omnitruck.chef.io/install.sh | \
- {{if .Sudo}}sudo{{end}} bash -s --{{if .Version}} -v {{.Version}}{{end}}
-```
-
-When guest_os_type is set to "windows", Packer uses the following command to
-install the latest version of Chef:
-
-```powershell
-powershell.exe -Command \". { iwr -useb https://omnitruck.chef.io/install.ps1 } | iex; install\"
-```
-
-This command can be customized using the `install_command` configuration.
diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json
index eae4579a3..e3ea0b705 100644
--- a/website/data/docs-nav-data.json
+++ b/website/data/docs-nav-data.json
@@ -828,14 +828,6 @@
"title": "Breakpoint",
"path": "provisioners/breakpoint"
},
- {
- "title": "Chef Client",
- "path": "provisioners/chef-client"
- },
- {
- "title": "Chef Solo",
- "path": "provisioners/chef-solo"
- },
{
"title": "Converge",
"path": "provisioners/converge"