Merge pull request #10921 from hashicorp/extract-chef

Extract Chef Plugins
This commit is contained in:
Megan Marsh 2021-04-20 13:42:55 -07:00 committed by GitHub
commit d8c3584b46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 393 additions and 1438 deletions

View File

@ -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),

View File

@ -19,6 +19,8 @@ import (
anazibimportpostprocessor "github.com/hashicorp/packer-plugin-amazon/post-processor/import"
ansibleprovisioner "github.com/hashicorp/packer-plugin-ansible/provisioner/ansible"
ansiblelocalprovisioner "github.com/hashicorp/packer-plugin-ansible/provisioner/ansible-local"
chefclientprovisioner "github.com/hashicorp/packer-plugin-chef/provisioner/chef-client"
chefsoloprovisioner "github.com/hashicorp/packer-plugin-chef/provisioner/chef-solo"
dockerbuilder "github.com/hashicorp/packer-plugin-docker/builder/docker"
dockerimportpostprocessor "github.com/hashicorp/packer-plugin-docker/post-processor/docker-import"
dockerpushpostprocessor "github.com/hashicorp/packer-plugin-docker/post-processor/docker-push"
@ -95,6 +97,8 @@ var VendoredBuilders = map[string]packersdk.Builder{
var VendoredProvisioners = map[string]packersdk.Provisioner{
"ansible": new(ansibleprovisioner.Provisioner),
"ansible-local": new(ansiblelocalprovisioner.Provisioner),
"chef-client": new(chefclientprovisioner.Provisioner),
"chef-solo": new(chefsoloprovisioner.Provisioner),
}
// VendoredPostProcessors are post-processor components that were once bundled with the

1
go.mod
View File

@ -40,6 +40,7 @@ require (
github.com/hashicorp/packer-plugin-alicloud v0.0.2
github.com/hashicorp/packer-plugin-amazon v0.0.1
github.com/hashicorp/packer-plugin-ansible v0.0.2
github.com/hashicorp/packer-plugin-chef v0.0.1
github.com/hashicorp/packer-plugin-docker v0.0.7
github.com/hashicorp/packer-plugin-googlecompute v0.0.1
github.com/hashicorp/packer-plugin-ncloud v0.0.2

2
go.sum
View File

@ -468,6 +468,8 @@ github.com/hashicorp/packer-plugin-amazon v0.0.1 h1:EuyjNK9bL7WhQeIJzhBJxOx8nyc6
github.com/hashicorp/packer-plugin-amazon v0.0.1/go.mod h1:12c9msibyHdId+Mk/pCbdRb1KaLIhaNyxeJ6n8bZt30=
github.com/hashicorp/packer-plugin-ansible v0.0.2 h1:nvBtCedXhUI5T6Up5+bmhlY7rmk8FjWuFv9A2joK7TU=
github.com/hashicorp/packer-plugin-ansible v0.0.2/go.mod h1:ocXB4KTU+I+DBRGfMP4XE7dPlURaUnb7NJvyddZ6bh0=
github.com/hashicorp/packer-plugin-chef v0.0.1 h1:1zQwnnvftwg9PJyWjMfHfDyzfWDdb0eo9IX8fX6kd+Y=
github.com/hashicorp/packer-plugin-chef v0.0.1/go.mod h1:4iSyWfvrb4QwUDZqJ3iCb+kIsnDwOTL1yTEDXBtk3Ew=
github.com/hashicorp/packer-plugin-docker v0.0.7 h1:hMTrH7vrkFIjphtbbtpuzffTzSjMNgxayo2DPLz9y+c=
github.com/hashicorp/packer-plugin-docker v0.0.7/go.mod h1:IpeKlwOSy2kdgQcysqd3gCsoqjME9jtmpFoKxn7RRNI=
github.com/hashicorp/packer-plugin-googlecompute v0.0.1 h1:Shjio88MraB+ocj0VI5+M65r4UBKbYI4eCqLNyPXKEo=

View File

@ -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())
}
}
}

View File

@ -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)
}

View File

@ -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"])
}
}

View File

@ -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)
}

373
vendor/github.com/hashicorp/packer-plugin-chef/LICENSE generated vendored Normal file
View File

@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@ -195,7 +195,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
errs, fmt.Errorf("server_url must be set"))
}
if p.config.SkipInstall == false && p.config.InstallCommand == p.guestOSTypeConfig.installCommand {
if !p.config.SkipInstall && p.config.InstallCommand == p.guestOSTypeConfig.installCommand {
if p.config.ChefLicense == "" {
p.config.ChefLicense = "accept-silent"
}

View File

@ -163,7 +163,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
p.config.StagingDir = p.guestOSTypeConfig.stagingDir
}
if p.config.SkipInstall == false && p.config.InstallCommand == p.guestOSTypeConfig.installCommand {
if !p.config.SkipInstall && p.config.InstallCommand == p.guestOSTypeConfig.installCommand {
if p.config.ChefLicense == "" {
p.config.ChefLicense = "accept-silent"
}

4
vendor/modules.txt vendored
View File

@ -507,6 +507,10 @@ github.com/hashicorp/packer-plugin-amazon/post-processor/import
## explicit
github.com/hashicorp/packer-plugin-ansible/provisioner/ansible
github.com/hashicorp/packer-plugin-ansible/provisioner/ansible-local
# github.com/hashicorp/packer-plugin-chef v0.0.1
## explicit
github.com/hashicorp/packer-plugin-chef/provisioner/chef-client
github.com/hashicorp/packer-plugin-chef/provisioner/chef-solo
# github.com/hashicorp/packer-plugin-docker v0.0.7
## explicit
github.com/hashicorp/packer-plugin-docker/builder/docker

View File

@ -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`}}"
})
```

View File

@ -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.
<Tabs>
<Tab heading="HCL2">
```hcl
provisioner "chef-solo" {
cookbook_paths = ["cookbooks"]
}
```
</Tab>
<Tab heading="JSON">
```json
"provisioners":[{
"type": "chef-solo",
"cookbook_paths": ["cookbooks"]
}]
```
</Tab>
</Tabs>
## Configuration Reference
The reference of available configuration options is listed below. No
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.
<Tabs>
<Tab heading="HCL2">
- `json_string` (string) - The JSON string can be encoded using the [jsonencode](/docs/templates/hcl_templates/functions/encoding/jsonencode)
template function.
```hcl
provisioner "chef-solo" {
json_string = jsonencode({
"a" = "b"
"foo" = {
"bar" = "val"
"number" = 1
}
})
}
```
</Tab>
<Tab heading="JSON">
- `json` (object) - This option is only available to old-style JSON templates.
```json
"provisioners":[{
"type": "chef-solo",
"json": {
"a": "b",
"foo": {
"bar": "val",
"number": 1
}
}
}]
```
</Tab>
</Tabs>
## Chef Configuration
By default, Packer uses a simple Chef configuration file in order to set the
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.

View File

@ -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"

View File

@ -18,6 +18,13 @@
"repo": "hashicorp/packer-plugin-amazon",
"version": "latest"
},
{
"title": "Chef",
"path": "chef",
"repo": "hashicorp/packer-plugin-chef",
"version": "latest",
"pluginTier": "community"
},
{
"title": "Docker",
"path": "docker",