diff --git a/plugins/provisioners/chef/config/chef_client.rb b/plugins/provisioners/chef/config/chef_client.rb index 9684d2b0e..4805310b3 100644 --- a/plugins/provisioners/chef/config/chef_client.rb +++ b/plugins/provisioners/chef/config/chef_client.rb @@ -1,7 +1,7 @@ -require File.expand_path("../base", __FILE__) - require "vagrant/util/which" +require_relative "base" + module VagrantPlugins module Chef module Config @@ -38,10 +38,14 @@ module VagrantPlugins def validate(machine) errors = _detected_errors errors.concat(validate_base(machine)) - errors << I18n.t("vagrant.config.chef.server_url_empty") if \ - !chef_server_url || chef_server_url.strip == "" - errors << I18n.t("vagrant.config.chef.validation_key_path") if \ - !validation_key_path + + if chef_server_url.to_s.strip.empty? + errors << I18n.t("vagrant.config.chef.server_url_empty") + end + + if validation_key_path.to_s.strip.empty? + errors << I18n.t("vagrant.config.chef.validation_key_path") + end if delete_client || delete_node if !Vagrant::Util::Which.which("knife") diff --git a/plugins/provisioners/chef/config/chef_solo.rb b/plugins/provisioners/chef/config/chef_solo.rb index 59c3b858e..524596962 100644 --- a/plugins/provisioners/chef/config/chef_solo.rb +++ b/plugins/provisioners/chef/config/chef_solo.rb @@ -1,4 +1,4 @@ -require File.expand_path("../base", __FILE__) +require_relative "base" module VagrantPlugins module Chef @@ -65,10 +65,14 @@ module VagrantPlugins def validate(machine) errors = _detected_errors errors.concat(validate_base(machine)) - errors << I18n.t("vagrant.config.chef.cookbooks_path_empty") if \ - !cookbooks_path || [cookbooks_path].flatten.empty? - errors << I18n.t("vagrant.config.chef.environment_path_required") if \ - environment && environments_path.empty? + + if [cookbooks_path].flatten.compact.empty? + errors << I18n.t("vagrant.config.chef.cookbooks_path_empty") + end + + if environment && environments_path.empty? + errors << I18n.t("vagrant.config.chef.environment_path_required") + end environments_path.each do |type, raw_path| next if type != :host @@ -76,7 +80,8 @@ module VagrantPlugins path = Pathname.new(raw_path).expand_path(machine.env.root_path) if !path.directory? errors << I18n.t("vagrant.config.chef.environment_path_missing", - path: raw_path.to_s) + path: raw_path.to_s + ) end end @@ -93,6 +98,8 @@ module VagrantPlugins # Make sure the path is an array config = [config] if !config.is_a?(Array) || config.first.is_a?(Symbol) + return [] if config.flatten.compact.empty? + # Make sure all the paths are in the proper format config.map do |path| path = [:host, path] if !path.is_a?(Array) diff --git a/plugins/provisioners/chef/config/chef_zero.rb b/plugins/provisioners/chef/config/chef_zero.rb new file mode 100644 index 000000000..993a3fab9 --- /dev/null +++ b/plugins/provisioners/chef/config/chef_zero.rb @@ -0,0 +1,30 @@ +require_relative "chef_solo" + +module VagrantPlugins + module Chef + module Config + class ChefZero < ChefSolo + attr_accessor :nodes_path + + def initialize + super + + @nodes_path = UNSET_VALUE + end + + def finalize! + super + + @nodes_path = [] if @nodes_path == UNSET_VALUE + + # Make sure the path is an array. + @nodes_path = prepare_folders_config(@nodes_path) + end + + def validate(machine) + { "chef zero provisioner" => super["chef solo provisioner"] } + end + end + end + end +end diff --git a/plugins/provisioners/chef/plugin.rb b/plugins/provisioners/chef/plugin.rb index afe068047..817de36a3 100644 --- a/plugins/provisioners/chef/plugin.rb +++ b/plugins/provisioners/chef/plugin.rb @@ -2,11 +2,10 @@ require "pathname" require "vagrant" +require_relative "command_builder" + module VagrantPlugins module Chef - root = Pathname.new(File.expand_path("../", __FILE__)) - autoload :CommandBuilder, root.join("command_builder") - class Plugin < Vagrant.plugin("2") name "chef" description <<-DESC @@ -15,24 +14,34 @@ module VagrantPlugins DESC config(:chef_solo, :provisioner) do - require File.expand_path("../config/chef_solo", __FILE__) + require_relative "config/chef_solo" Config::ChefSolo end config(:chef_client, :provisioner) do - require File.expand_path("../config/chef_client", __FILE__) + require_relative "config/chef_client" Config::ChefClient end + config(:chef_zero, :provisioner) do + require_relative "config/chef_zero" + Config::ChefZero + end + provisioner(:chef_solo) do - require File.expand_path("../provisioner/chef_solo", __FILE__) + require_relative "provisioner/chef_solo" Provisioner::ChefSolo end provisioner(:chef_client) do - require File.expand_path("../provisioner/chef_client", __FILE__) + require_relative "provisioner/chef_client" Provisioner::ChefClient end + + provisioner(:chef_zero) do + require_relative "provisioner/chef_zero" + Provisioner::ChefZero + end end end end diff --git a/plugins/provisioners/chef/provisioner/chef_client.rb b/plugins/provisioners/chef/provisioner/chef_client.rb index d91b3c22c..9b0c2341f 100644 --- a/plugins/provisioners/chef/provisioner/chef_client.rb +++ b/plugins/provisioners/chef/provisioner/chef_client.rb @@ -3,7 +3,7 @@ require 'pathname' require 'vagrant' require 'vagrant/util/subprocess' -require File.expand_path("../base", __FILE__) +require_relative "base" module VagrantPlugins module Chef diff --git a/plugins/provisioners/chef/provisioner/chef_solo.rb b/plugins/provisioners/chef/provisioner/chef_solo.rb index bf66c99d5..a8c1e84d3 100644 --- a/plugins/provisioners/chef/provisioner/chef_solo.rb +++ b/plugins/provisioners/chef/provisioner/chef_solo.rb @@ -2,7 +2,7 @@ require "log4r" require "vagrant/util/counter" -require File.expand_path("../base", __FILE__) +require_relative "base" module VagrantPlugins module Chef @@ -19,6 +19,7 @@ module VagrantPlugins def initialize(machine, config) super @logger = Log4r::Logger.new("vagrant::provisioners::chef_solo") + @shared_folders = [] end def configure(root_config) @@ -36,13 +37,11 @@ module VagrantPlugins def provision # Verify that the proper shared folders exist. check = [] - [@cookbook_folders, @role_folders, @data_bags_folders, @environments_folders].each do |folders| - folders.each do |type, local_path, remote_path| - # We only care about checking folders that have a local path, meaning - # they were shared from the local machine, rather than assumed to - # exist on the VM. - check << remote_path if local_path - end + @shared_folders.each do |type, local_path, remote_path| + # We only care about checking folders that have a local path, meaning + # they were shared from the local machine, rather than assumed to + # exist on the VM. + check << remote_path if local_path end chown_provisioning_folder @@ -113,20 +112,21 @@ module VagrantPlugins root_config.vm.synced_folder(local_path, remote_path, opts) end end + @shared_folders += folders end def setup_solo_config - cookbooks_path = guest_paths(@cookbook_folders) - roles_path = guest_paths(@role_folders) - data_bags_path = guest_paths(@data_bags_folders).first - environments_path = guest_paths(@environments_folders).first - setup_config("provisioners/chef_solo/solo", "solo.rb", { - cookbooks_path: cookbooks_path, + setup_config("provisioners/chef_solo/solo", "solo.rb", solo_config) + end + + def solo_config + { + cookbooks_path: guest_paths(@cookbook_folders), recipe_url: @config.recipe_url, - roles_path: roles_path, - data_bags_path: data_bags_path, - environments_path: environments_path, - }) + roles_path: guest_paths(@role_folders), + data_bags_path: guest_paths(@data_bags_folders).first, + environments_path: guest_paths(@environments_folders).first + } end def run_chef_solo diff --git a/plugins/provisioners/chef/provisioner/chef_zero.rb b/plugins/provisioners/chef/provisioner/chef_zero.rb new file mode 100644 index 000000000..8ccae6130 --- /dev/null +++ b/plugins/provisioners/chef/provisioner/chef_zero.rb @@ -0,0 +1,34 @@ +require "log4r" + +require_relative "chef_solo" + +module VagrantPlugins + module Chef + module Provisioner + # This class implements provisioning via chef-zero. + class ChefZero < ChefSolo + attr_reader :node_folders + + def initialize(machine, config) + super + @logger = Log4r::Logger.new("vagrant::provisioners::chef_zero") + end + + def configure(root_config) + super + + @node_folders = expanded_folders(@config.nodes_path, "nodes") + + share_folders(root_config, "csn", @node_folders) + end + + def solo_config + super.merge( + local_mode: true, + node_path: guest_paths(@node_folders).first + ) + end + end + end + end +end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 333091fbb..929a5c338 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -1310,8 +1310,8 @@ en: Cookbook path doesn't exist: %{path} custom_config_path_missing: |- Path specified for "custom_config_path" does not exist. - server_url_empty: "Chef server URL must be populated." - validation_key_path: "Validation key path must be valid path to your chef server validation key." + server_url_empty: "Chef Server URL must be populated." + validation_key_path: "Validation key path must be valid path to your Chef Server validation key." loader: bad_v1_key: |- Unknown configuration section '%{key}'. If this section was part of diff --git a/templates/provisioners/chef_solo/solo.erb b/templates/provisioners/chef_solo/solo.erb index fd52fff91..b7d08a65b 100644 --- a/templates/provisioners/chef_solo/solo.erb +++ b/templates/provisioners/chef_solo/solo.erb @@ -32,6 +32,13 @@ environment_path <%= environments_path.inspect %> environment "<%= environment %>" <% end -%> +<% if local_mode -%> +local_mode true +<% end -%> +<% if node_path -%> +node_path <%= node_path.inspect %> +<% end -%> + http_proxy <%= http_proxy.inspect %> http_proxy_user <%= http_proxy_user.inspect %> http_proxy_pass <%= http_proxy_pass.inspect %> diff --git a/test/unit/plugins/provisioners/chef/config/base_test.rb b/test/unit/plugins/provisioners/chef/config/base_test.rb new file mode 100644 index 000000000..062c48b08 --- /dev/null +++ b/test/unit/plugins/provisioners/chef/config/base_test.rb @@ -0,0 +1,262 @@ +require_relative "../../../../base" + +require Vagrant.source_root.join("plugins/provisioners/chef/config/base") + +describe VagrantPlugins::Chef::Config::Base do + include_context "unit" + + subject { described_class.new } + + let(:machine) { double("machine") } + + describe "#arguments" do + it "defaults to nil" do + subject.finalize! + expect(subject.arguments).to be(nil) + end + end + + describe "#attempts" do + it "defaults to 1" do + subject.finalize! + expect(subject.attempts).to eq(1) + end + end + + describe "#binary_path" do + it "defaults to nil" do + subject.finalize! + expect(subject.binary_path).to be(nil) + end + end + + describe "#binary_env" do + it "defaults to nil" do + subject.finalize! + expect(subject.binary_env).to be(nil) + end + end + + describe "#custom_config_path" do + it "defaults to nil" do + subject.finalize! + expect(subject.custom_config_path).to be(nil) + end + end + + describe "#environment" do + it "defaults to nil" do + subject.finalize! + expect(subject.environment).to be(nil) + end + end + + describe "#formatter" do + it "defaults to nil" do + subject.finalize! + expect(subject.formatter).to be(nil) + end + end + + describe "#http_proxy" do + it "defaults to nil" do + subject.finalize! + expect(subject.http_proxy).to be(nil) + end + end + + describe "#http_proxy_user" do + it "defaults to nil" do + subject.finalize! + expect(subject.http_proxy_user).to be(nil) + end + end + + describe "#http_proxy_pass" do + it "defaults to nil" do + subject.finalize! + expect(subject.http_proxy_pass).to be(nil) + end + end + + describe "#https_proxy" do + it "defaults to nil" do + subject.finalize! + expect(subject.https_proxy).to be(nil) + end + end + + describe "#https_proxy_user" do + it "defaults to nil" do + subject.finalize! + expect(subject.https_proxy_user).to be(nil) + end + end + + describe "#https_proxy_pass" do + it "defaults to nil" do + subject.finalize! + expect(subject.https_proxy_pass).to be(nil) + end + end + + describe "#log_level" do + it "defaults to :info" do + subject.finalize! + expect(subject.log_level).to be(:info) + end + + it "is converted to a symbol" do + subject.log_level = "foo" + subject.finalize! + expect(subject.log_level).to eq(:foo) + end + end + + describe "#no_proxy" do + it "defaults to nil" do + subject.finalize! + expect(subject.no_proxy).to be(nil) + end + end + + describe "#node_name" do + it "defaults to nil" do + subject.finalize! + expect(subject.node_name).to be(nil) + end + end + + describe "#provisioning_path" do + it "defaults to a tmp_path" do + subject.finalize! + expect(subject.provisioning_path).to match(%r{/tmp/vagrant-chef-\d+}) + end + end + + describe "#file_backup_path" do + it "defaults to /var/chef/backup" do + subject.finalize! + expect(subject.file_backup_path).to eq("/var/chef/backup") + end + end + + describe "#file_cache_path" do + it "defaults to /var/chef/cache" do + subject.finalize! + expect(subject.file_cache_path).to eq("/var/chef/cache") + end + end + + describe "#verbose_logging" do + it "defaults to false" do + subject.finalize! + expect(subject.verbose_logging).to be(false) + end + end + + describe "#run_list" do + it "defaults to an empty array" do + subject.finalize! + expect(subject.run_list).to be_a(Array) + expect(subject.run_list).to be_empty + end + end + + describe "#json" do + it "defaults to an empty hash" do + subject.finalize! + expect(subject.json).to be_a(Hash) + expect(subject.json).to be_empty + end + end + + describe "#add_recipe" do + context "when the prefix is given" do + it "adds the value to the run_list" do + subject.add_recipe("recipe[foo::bar]") + expect(subject.run_list).to eq %w(recipe[foo::bar]) + end + end + + context "when the prefix is not given" do + it "adds the prefixed value to the run_list" do + subject.add_recipe("foo::bar") + expect(subject.run_list).to eq %w(recipe[foo::bar]) + end + end + end + + describe "#add_role" do + context "when the prefix is given" do + it "adds the value to the run_list" do + subject.add_role("role[foo]") + expect(subject.run_list).to eq %w(role[foo]) + end + end + + context "when the prefix is not given" do + it "adds the prefixed value to the run_list" do + subject.add_role("foo") + expect(subject.run_list).to eq %w(role[foo]) + end + end + end + + describe "#validate_base" do + context "when #custom_config_path does not exist" do + let(:path) { "/path/to/file" } + + before do + allow(File).to receive(:file?) + .with(path) + .and_return(false) + + allow(machine).to receive(:env) + .and_return(double("env", + root_path: "", + )) + end + + it "returns an error" do + subject.custom_config_path = path + subject.finalize! + + expect(subject.validate_base(machine)) + .to eq ['Path specified for "custom_config_path" does not exist.'] + end + end + end + + describe "#merge" do + it "merges the json hash" do + a = described_class.new.tap do |i| + i.json = { "foo" => "bar" } + end + b = described_class.new.tap do |i| + i.json = { "zip" => "zap" } + end + + result = a.merge(b) + expect(result.json).to eq( + "foo" => "bar", + "zip" => "zap", + ) + end + + it "appends the run_list array" do + a = described_class.new.tap do |i| + i.run_list = ["recipe[foo::bar]"] + end + b = described_class.new.tap do |i| + i.run_list = ["recipe[zip::zap]"] + end + + result = a.merge(b) + expect(result.run_list).to eq %w( + recipe[foo::bar] + recipe[zip::zap] + ) + end + end +end diff --git a/test/unit/plugins/provisioners/chef/config/chef_client_test.rb b/test/unit/plugins/provisioners/chef/config/chef_client_test.rb new file mode 100644 index 000000000..17f2dc321 --- /dev/null +++ b/test/unit/plugins/provisioners/chef/config/chef_client_test.rb @@ -0,0 +1,136 @@ +require_relative "../../../../base" + +require Vagrant.source_root.join("plugins/provisioners/chef/config/chef_client") + +describe VagrantPlugins::Chef::Config::ChefClient do + include_context "unit" + + subject { described_class.new } + + let(:machine) { double("machine") } + + describe "#chef_server_url" do + it "defaults to nil" do + subject.finalize! + expect(subject.chef_server_url).to be(nil) + end + end + + describe "#client_key_path" do + it "defaults to /etc/chef/client.pem" do + subject.finalize! + expect(subject.client_key_path).to eq("/etc/chef/client.pem") + end + end + + describe "#delete_client" do + it "defaults to false" do + subject.finalize! + expect(subject.delete_client).to be(false) + end + end + + describe "#delete_node" do + it "defaults to false" do + subject.finalize! + expect(subject.delete_node).to be(false) + end + end + + describe "#validation_key_path" do + it "defaults to nil" do + subject.finalize! + expect(subject.validation_key_path).to be(nil) + end + end + + describe "#validation_client_name" do + it "defaults to chef-validator" do + subject.finalize! + expect(subject.validation_client_name).to eq("chef-validator") + end + end + + describe "#validate" do + before do + allow(machine).to receive(:env) + .and_return(double("env", + root_path: "", + )) + + subject.chef_server_url = "https://example.com" + subject.validation_key_path = "/path/to/key.pem" + end + + let(:result) { subject.validate(machine) } + let(:errors) { result["chef client provisioner"] } + + context "when the chef_server_url is nil" do + it "returns an error" do + subject.chef_server_url = nil + subject.finalize! + expect(errors).to eq([I18n.t("vagrant.config.chef.server_url_empty")]) + end + end + + context "when the chef_server_url is blank" do + it "returns an error" do + subject.chef_server_url = " " + subject.finalize! + expect(errors).to eq([I18n.t("vagrant.config.chef.server_url_empty")]) + end + end + + context "when the validation_key_path is nil" do + it "returns an error" do + subject.validation_key_path = nil + subject.finalize! + expect(errors).to eq([I18n.t("vagrant.config.chef.validation_key_path")]) + end + end + + context "when the validation_key_path is blank" do + it "returns an error" do + subject.validation_key_path = " " + subject.finalize! + expect(errors).to eq([I18n.t("vagrant.config.chef.validation_key_path")]) + end + end + + context "when #delete_client is given" do + before { subject.delete_client = true } + + context "when knife does not exist" do + before do + allow(Vagrant::Util::Which) + .to receive(:which) + .with("knife") + .and_return(nil) + end + + it "returns an error" do + subject.finalize! + expect(errors).to eq([I18n.t("vagrant.chef_config_knife_not_found")]) + end + end + end + + context "when #delete_node is given" do + before { subject.delete_node = true } + + context "when knife does not exist" do + before do + allow(Vagrant::Util::Which) + .to receive(:which) + .with("knife") + .and_return(nil) + end + + it "returns an error" do + subject.finalize! + expect(errors).to eq([I18n.t("vagrant.chef_config_knife_not_found")]) + end + end + end + end +end diff --git a/test/unit/plugins/provisioners/chef/config/chef_solo_test.rb b/test/unit/plugins/provisioners/chef/config/chef_solo_test.rb new file mode 100644 index 000000000..d6a2a03af --- /dev/null +++ b/test/unit/plugins/provisioners/chef/config/chef_solo_test.rb @@ -0,0 +1,147 @@ +require_relative "../../../../base" + +require Vagrant.source_root.join("plugins/provisioners/chef/config/chef_solo") + +describe VagrantPlugins::Chef::Config::ChefSolo do + include_context "unit" + + subject { described_class.new } + + let(:machine) { double("machine") } + + describe "#cookbooks_path" do + it "defaults to something" do + subject.finalize! + expect(subject.cookbooks_path).to eq([ + [:host, "cookbooks"], + [:vm, "cookbooks"], + ]) + end + end + + describe "#data_bags_path" do + it "defaults to an empty array" do + subject.finalize! + expect(subject.data_bags_path).to be_a(Array) + expect(subject.data_bags_path).to be_empty + end + end + + describe "#environments_path" do + it "defaults to an empty array" do + subject.finalize! + expect(subject.environments_path).to be_a(Array) + expect(subject.environments_path).to be_empty + end + + it "merges deeply nested paths" do + subject.environments_path = ["/foo", "/bar", ["/zip"]] + subject.finalize! + expect(subject.environments_path) + .to eq([:host, :host, :host].zip %w(/foo /bar /zip)) + end + end + + describe "#recipe_url" do + it "defaults to nil" do + subject.finalize! + expect(subject.recipe_url).to be(nil) + end + end + + describe "#roles_path" do + it "defaults to an empty array" do + subject.finalize! + expect(subject.roles_path).to be_a(Array) + expect(subject.roles_path).to be_empty + end + end + + describe "#synced_folder_type" do + it "defaults to nil" do + subject.finalize! + expect(subject.synced_folder_type).to be(nil) + end + end + + describe "#validate" do + before do + allow(machine).to receive(:env) + .and_return(double("env", + root_path: "", + )) + + subject.cookbooks_path = ["/cookbooks", "/more/cookbooks"] + end + + let(:result) { subject.validate(machine) } + let(:errors) { result["chef solo provisioner"] } + + context "when the cookbooks_path is nil" do + it "returns an error" do + subject.cookbooks_path = nil + subject.finalize! + expect(errors).to eq [I18n.t("vagrant.config.chef.cookbooks_path_empty")] + end + end + + context "when the cookbooks_path is an empty array" do + it "returns an error" do + subject.cookbooks_path = [] + subject.finalize! + expect(errors).to eq [I18n.t("vagrant.config.chef.cookbooks_path_empty")] + end + end + + context "when the cookbooks_path is an array with nil" do + it "returns an error" do + subject.cookbooks_path = [nil, nil] + subject.finalize! + expect(errors).to eq [I18n.t("vagrant.config.chef.cookbooks_path_empty")] + end + end + + context "when environments is given" do + before do + subject.environment = "production" + end + + context "when the environments_path is nil" do + it "returns an error" do + subject.environments_path = nil + subject.finalize! + expect(errors).to eq [I18n.t("vagrant.config.chef.environment_path_required")] + end + end + + context "when the environments_path is an empty array" do + it "returns an error" do + subject.environments_path = [] + subject.finalize! + expect(errors).to eq [I18n.t("vagrant.config.chef.environment_path_required")] + end + end + + context "when the environments_path is an array with nil" do + it "returns an error" do + subject.environments_path = [nil, nil] + subject.finalize! + expect(errors).to eq [I18n.t("vagrant.config.chef.environment_path_required")] + end + end + + context "when the environments_path does not exist" do + it "returns an error" do + env_path = "/path/to/environments/that/will/never/exist" + subject.environments_path = env_path + subject.finalize! + expect(errors).to eq [ + I18n.t("vagrant.config.chef.environment_path_missing", + path: env_path + ) + ] + end + end + end + end +end diff --git a/test/unit/plugins/provisioners/chef/config/chef_zero_test.rb b/test/unit/plugins/provisioners/chef/config/chef_zero_test.rb new file mode 100644 index 000000000..6149a3bde --- /dev/null +++ b/test/unit/plugins/provisioners/chef/config/chef_zero_test.rb @@ -0,0 +1,19 @@ +require_relative "../../../../base" + +require Vagrant.source_root.join("plugins/provisioners/chef/config/chef_zero") + +describe VagrantPlugins::Chef::Config::ChefZero do + include_context "unit" + + subject { described_class.new } + + let(:machine) { double("machine") } + + describe "#nodes_path" do + it "defaults to an array" do + subject.finalize! + expect(subject.nodes_path).to be_a(Array) + expect(subject.nodes_path).to be_empty + end + end +end diff --git a/website/docs/source/v2/provisioning/chef_common.html.md b/website/docs/source/v2/provisioning/chef_common.html.md index 1a41691ed..ed776ad0c 100644 --- a/website/docs/source/v2/provisioning/chef_common.html.md +++ b/website/docs/source/v2/provisioning/chef_common.html.md @@ -5,11 +5,11 @@ sidebar_current: "provisioning-chefcommon" # Shared Chef Options -This page documents the list of available options that are available in -both the -[Chef solo](/v2/provisioning/chef_solo.html) +This page documents the list of available options that are available in the +[Chef Solo](/v2/provisioning/chef_solo.html), +[Chef Zero](/v2/provisioning/chef_zero.html) and -[Chef client](/v2/provisioning/chef_client.html) +[Chef Client](/v2/provisioning/chef_client.html) provisioners. * `arguments` (string) - A list of additional arguments to pass on the diff --git a/website/docs/source/v2/provisioning/chef_solo.html.md b/website/docs/source/v2/provisioning/chef_solo.html.md index cb8e34ac8..d916f4fe2 100644 --- a/website/docs/source/v2/provisioning/chef_solo.html.md +++ b/website/docs/source/v2/provisioning/chef_solo.html.md @@ -34,7 +34,7 @@ available below this section. Note that only the Chef-solo specific options are shown below. There is also a large set of [common options](/v2/provisioning/chef_common.html) -that are available with both the Chef Solo and Chef client provisioners. +that are available with all Chef provisioners. * `cookbooks_path` (string or array) - A list of paths to where cookbooks are stored. By default this is "cookbooks", expecting a cookbooks folder diff --git a/website/docs/source/v2/provisioning/chef_zero.html.md b/website/docs/source/v2/provisioning/chef_zero.html.md new file mode 100644 index 000000000..f716d3ff9 --- /dev/null +++ b/website/docs/source/v2/provisioning/chef_zero.html.md @@ -0,0 +1,64 @@ +--- +page_title: "Chef Zero - Provisioning" +sidebar_current: "provisioning-chefzero" +--- + +# Chef Zero Provisioner + +**Provisioner name: `chef_zero`** + +The Chef Zero provisioner allows you to provision the guest using +[Chef](https://www.getchef.com/chef/), specifically with +[Chef Zero/local mode](https://docs.getchef.com/ctl_chef_client.html#run-in-local-mode). + +This new provisioner is a middle ground between running a full blown +Chef Server and using the limited [Chef Solo](/v2/provisioning/chef_solo.html) +provisioner. It runs a local in-memory Chef Server and fakes the validation +and client key registration. + +
+

+ Warning: If you're not familiar with Chef and Vagrant already, + I recommend starting with the shell + provisioner. However, if you're comfortable with Vagrant already, Vagrant + is the best way to learn Chef. +

+
+ +## Options + +This section lists the complete set of available options for the Chef Zero +provisioner. More detailed examples of how to use the provisioner are +available below this section. + +Note that only the Chef Zero specific options are shown below, but all [Chef +Solo options](/v2/provisioning/chef_solo.html), including the [common Chef +provisioner options](/v2/provisioning/chef_common.html), are also inherited. + +* `nodes_path` (string) - A path where the Chef nodes are stored. Be default, + no node path is set. + +## Usage + +The Chef Zero provisioner is configured basically the same way as the Chef Solo +provisioner. See the [Chef Solo documentations](/v2/provisioning/chef_solo.html) +for more information. + +A basic example could look like this: + +```ruby +Vagrant.configure("2") do |config| + config.vm.provision "chef_zero" do |chef| + # Specify the local paths where Chef data is stored + chef.cookbooks_path = "cookbooks" + chef.roles_path = "roles" + chef.nodes_path = "nodes" + + # Add a recipe + chef.add_recipe "apache" + + # Or maybe a role + chef.add_role "web" + end +end +```