Merge pull request #6557 from mitchellh/sethvargo/chef_windows

Allow ChefDK installation, add Windows installer support
This commit is contained in:
Seth Vargo 2015-11-19 15:11:05 -08:00
commit ae35dd6218
15 changed files with 180 additions and 112 deletions

View File

@ -5,11 +5,11 @@ module VagrantPlugins
module Cap
module Debian
module ChefInstall
def self.chef_install(machine, version, prerelease, download_path)
def self.chef_install(machine, project, version, channel, options = {})
machine.communicate.sudo("apt-get update -y -qq")
machine.communicate.sudo("apt-get install -y -qq curl")
command = Omnibus.build_command(version, prerelease, download_path)
command = Omnibus.sh_command(project, version, channel, options)
machine.communicate.sudo(command)
end
end

View File

@ -5,13 +5,13 @@ module VagrantPlugins
module Cap
module OmniOS
module ChefInstall
def self.chef_install(machine, version, prerelease, download_path)
su_cmd = machine.config.solaris.suexec_cmd
def self.chef_install(machine, project, version, channel, options = {})
su = machine.config.solaris.suexec_cmd
machine.communicate.execute("#{su_cmd} pkg list --no-refresh web/curl > /dev/null 2>&1 || pkg install -q --accept web/curl")
machine.communicate.execute("#{su} pkg list --no-refresh web/curl > /dev/null 2>&1 || pkg install -q --accept web/curl")
command = VagrantPlugins::Chef::Omnibus.build_command(version, prerelease, download_path)
machine.communicate.execute(su_cmd + ' ' + command)
command = Omnibus.sh_command(project, version, channel, options)
machine.communicate.execute("#{su} #{command}")
end
end
end

View File

@ -5,14 +5,14 @@ module VagrantPlugins
module Cap
module Redhat
module ChefInstall
def self.chef_install(machine, version, prerelease, download_path)
def self.chef_install(machine, project, version, channel, options = {})
if dnf?(machine)
machine.communicate.sudo("dnf install -y -q curl")
else
machine.communicate.sudo("yum install -y -q curl")
end
command = Omnibus.build_command(version, prerelease, download_path)
command = Omnibus.sh_command(project, version, channel, options)
machine.communicate.sudo(command)
end

View File

@ -0,0 +1,16 @@
require_relative "../../omnibus"
module VagrantPlugins
module Chef
module Cap
module Windows
module ChefInstall
def self.chef_install(machine, project, version, channel, options = {})
command = Omnibus.ps_command(project, version, channel, options)
machine.communicate.sudo(command)
end
end
end
end
end
end

View File

@ -50,7 +50,7 @@ module VagrantPlugins
args << " --log_level #{config.log_level}" if config.log_level
args << " --no-color" if !options[:colored]
if config.install && config.version >= "11.0"
if config.install && (config.version == :latest || config.version >= "11.0")
args << " --force-formatter"
end

View File

@ -11,6 +11,12 @@ module VagrantPlugins
# @return [String]
attr_accessor :binary_env
# The name of the Chef project to install. This is "chef" for the Chef
# Client or "chefdk" for the Chef Development Kit. Other product names
# may be available as well.
# @return [String]
attr_accessor :product
# Install Chef on the system if it does not exist. Default is true.
# This is a trinary attribute (it can have three values):
#
@ -26,9 +32,11 @@ module VagrantPlugins
# @return [String, Symbol]
attr_accessor :log_level
# Install a prerelease version of Chef.
# @return [true, false]
attr_accessor :prerelease
# The channel from which to download Chef. Currently known values are
# "current" and "stable", but more may be added in the future. The
# default is "current".
# @return [String]
attr_accessor :channel
# The version of Chef to install. If Chef is already installed on the
# system, the installed version is compared with the requested version.
@ -52,25 +60,38 @@ module VagrantPlugins
# @return [String]
attr_accessor :installer_download_path
# @deprecated
def prerelease=(value)
STDOUT.puts <<-EOH
[DEPRECATED] The configuration `chef.prerelease' has been deprecated. Please use
`chef.channel' instead. The default value for channel is "current", which
includes prelease versions of Chef Client and the Chef Development Kit. You can
probably just remove the `prerelease' setting from your Vagrantfile and things
will continue working as expected.
EOH
end
def initialize
super
@binary_path = UNSET_VALUE
@binary_env = UNSET_VALUE
@product = UNSET_VALUE
@install = UNSET_VALUE
@log_level = UNSET_VALUE
@prerelease = UNSET_VALUE
@channel = UNSET_VALUE
@version = UNSET_VALUE
@installer_download_path = UNSET_VALUE
end
def finalize!
@binary_path = nil if @binary_path == UNSET_VALUE
@binary_env = nil if @binary_env == UNSET_VALUE
@install = true if @install == UNSET_VALUE
@log_level = :info if @log_level == UNSET_VALUE
@prerelease = false if @prerelease == UNSET_VALUE
@version = :latest if @version == UNSET_VALUE
@binary_path = nil if @binary_path == UNSET_VALUE
@binary_env = nil if @binary_env == UNSET_VALUE
@product = "chef" if @product == UNSET_VALUE
@install = true if @install == UNSET_VALUE
@log_level = :info if @log_level == UNSET_VALUE
@channel = "current" if @channel == UNSET_VALUE
@version = :latest if @version == UNSET_VALUE
@installer_download_path = nil if @installer_download_path == UNSET_VALUE
# Make sure the install is a symbol if it's not a boolean

View File

@ -61,12 +61,6 @@ module VagrantPlugins
@run_list = []
end
def encrypted_data_bag_secret=(value)
puts "DEPRECATION: Chef encrypted_data_bag_secret has no effect anymore."
puts "Remove this from your Vagrantfile since it'll be removed in the next"
puts "Vagrant version."
end
def finalize!
super

View File

@ -3,10 +3,11 @@ module VagrantPlugins
class Installer
def initialize(machine, options = {})
@machine = machine
@version = options.fetch(:version, :latest)
@prerelease = options.fetch(:prerelease, :latest)
@force = options.fetch(:force, false)
@download_path = options.fetch(:download_path, nil)
@product = options.fetch(:product)
@channel = options.fetch(:channel)
@version = options.fetch(:version)
@force = options.fetch(:force)
@options = options.dup
end
# This handles verifying the Chef installation, installing it if it was
@ -28,7 +29,7 @@ module VagrantPlugins
@machine.ui.detail(I18n.t("vagrant.chef_installing",
version: @version.to_s))
@machine.guest.capability(:chef_install, @version, @prerelease, @download_path)
@machine.guest.capability(:chef_install, @product, @version, @channel, @options)
if !@machine.guest.capability(:chef_installed, @version)
raise Provisioner::Base::ChefError, :install_failed

View File

@ -1,32 +1,39 @@
module VagrantPlugins
module Chef
# Read more about the Omnibus installer here:
#
# https://docs.chef.io/install_omnibus.html
#
module Omnibus
OMNITRUCK = "https://www.chef.io/chef/install.sh".freeze
OMNITRUCK = "https://omnitruck.chef.io".freeze
# Read more about the Omnibus installer here:
# https://docs.getchef.com/install_omnibus.html
def build_command(version, prerelease = false, download_path = nil)
command = "curl -sL #{OMNITRUCK} | sudo bash"
if prerelease || version != :latest || download_path != nil
command << " -s --"
end
if prerelease
command << " -p"
end
def sh_command(project, version, channel, options = {})
command = "curl -sL #{OMNITRUCK}/install.sh | sudo bash"
command << " -s -- -P \"#{project}\" -c \"#{channel}\""
if version != :latest
command << " -v \"#{version}\""
end
if download_path
command << " -d \"#{download_path}\""
if options[:download_path]
command << " -d \"#{options[:download_path]}\""
end
command
end
module_function :build_command
module_function :sh_command
def ps_command(project, version, channel, options = {})
command = ". { iwr -useb #{OMNITRUCK}/install.ps1 } | iex; install"
command << " -project '#{project}' -channel '#{channel}'"
if version != :latest
command << " -version '#{version}'"
end
command
end
module_function :ps_command
end
end
end

View File

@ -53,29 +53,14 @@ module VagrantPlugins
Provisioner::ChefZero
end
guest_capability(:linux, :chef_installed) do
require_relative "cap/linux/chef_installed"
Cap::Linux::ChefInstalled
end
guest_capability(:windows, :chef_installed) do
require_relative "cap/windows/chef_installed"
Cap::Windows::ChefInstalled
end
guest_capability(:debian, :chef_install) do
require_relative "cap/debian/chef_install"
Cap::Debian::ChefInstall
end
guest_capability(:redhat, :chef_install) do
require_relative "cap/redhat/chef_install"
Cap::Redhat::ChefInstall
end
guest_capability(:omnios, :chef_installed) do
require_relative "cap/omnios/chef_installed"
Cap::OmniOS::ChefInstalled
guest_capability(:linux, :chef_installed) do
require_relative "cap/linux/chef_installed"
Cap::Linux::ChefInstalled
end
guest_capability(:omnios, :chef_install) do
@ -83,6 +68,25 @@ module VagrantPlugins
Cap::OmniOS::ChefInstall
end
guest_capability(:omnios, :chef_installed) do
require_relative "cap/omnios/chef_installed"
Cap::OmniOS::ChefInstalled
end
guest_capability(:redhat, :chef_install) do
require_relative "cap/redhat/chef_install"
Cap::Redhat::ChefInstall
end
guest_capability(:windows, :chef_install) do
require_relative "cap/windows/chef_install"
Cap::Windows::ChefInstall
end
guest_capability(:windows, :chef_installed) do
require_relative "cap/windows/chef_installed"
Cap::Windows::ChefInstalled
end
end
end
end

View File

@ -42,9 +42,10 @@ module VagrantPlugins
@logger.info("Checking for Chef installation...")
installer = Installer.new(@machine,
force: config.install == :force,
version: config.version,
prerelease: config.prerelease,
product: config.product,
channel: config.channel,
version: config.version,
force: config.install == :force,
download_path: config.installer_download_path
)
installer.ensure_installed

View File

@ -145,7 +145,20 @@ module VagrantPlugins
command = "knife #{deletable} delete #{node_name}"
command << " --config '#{guest_client_rb_path}'"
command << " --yes"
@machine.communicate.sudo(command, error_check: true)
output = []
result = @machine.communicate.sudo(command, error_check: false) do |_, data|
output << data
end
if result != 0
@machine.ui.error("There were errors removing the #{deletable} from the Chef Server:")
@machine.ui.error("")
@machine.ui.error(output.join("\n"))
@machine.ui.error("")
@machine.ui.error("Vagrant will continue destroying the virtual machine, but you may need")
@machine.ui.error("to manually delete the #{deletable} from the Chef Server!")
end
end
end
end

View File

@ -23,6 +23,13 @@ describe VagrantPlugins::Chef::Config::Base do
end
end
describe "#product" do
it "defaults to \"chef\"" do
subject.finalize!
expect(subject.product).to eq("chef")
end
end
describe "#install" do
it "defaults to true" do
subject.finalize!
@ -49,10 +56,18 @@ describe VagrantPlugins::Chef::Config::Base do
end
end
describe "#prerelease" do
it "defaults to true" do
describe "#channel" do
it "defaults to \"current\"" do
subject.finalize!
expect(subject.prerelease).to be(false)
expect(subject.channel).to eq("current")
end
end
describe "#prerelease" do
it "should not exist in Vagrant 1.9" do
if Vagrant::VERSION >= "1.9"
raise "This option should be removed!"
end
end
end

View File

@ -3,53 +3,44 @@ require_relative "../../../base"
require Vagrant.source_root.join("plugins/provisioners/chef/omnibus")
describe VagrantPlugins::Chef::Omnibus do
let(:prefix) { "curl -sL #{described_class.const_get(:OMNITRUCK)}" }
describe "#sh_command" do
it "includes the project name" do
command = described_class.sh_command("chef", nil, "stable")
expect(command).to include %|-P "chef"|
end
let(:version) { :latest }
let(:prerelease) { false }
let(:download_path) { nil }
it "includes the channel" do
command = described_class.sh_command("chef", nil, "stable")
expect(command).to include %|-c "stable"|
end
let(:build_command) { described_class.build_command(version, prerelease, download_path) }
it "includes the version" do
command = described_class.sh_command("chef", "1.2.3", "stable")
expect(command).to include %|-v "1.2.3"|
end
context "when prerelease is given" do
let(:prerelease) { true }
it "returns the correct command" do
expect(build_command).to eq("#{prefix} | sudo bash -s -- -p")
it "includes the download path" do
command = described_class.sh_command("chef", "1.2.3", "stable",
download_path: "/some/path",
)
expect(command).to include %|-d "/some/path"|
end
end
context "when download_path is given" do
let(:download_path) { '/tmp/path/to/omnibuses' }
it "returns the correct command" do
expect(build_command).to eq("#{prefix} | sudo bash -s -- -d \"/tmp/path/to/omnibuses\"")
describe "#ps_command" do
it "includes the project name" do
command = described_class.ps_command("chef", nil, "stable")
expect(command).to include %|-project 'chef'|
end
end
context "when version is :latest" do
let(:version) { :latest }
it "returns the correct command" do
expect(build_command).to eq("#{prefix} | sudo bash")
it "includes the channel" do
command = described_class.ps_command("chef", nil, "stable")
expect(command).to include %|-channel 'stable'|
end
end
context "when version is a string" do
let(:version) { "1.2.3" }
it "returns the correct command" do
expect(build_command).to eq("#{prefix} | sudo bash -s -- -v \"1.2.3\"")
end
end
context "when prerelease and version and download_path are given" do
let(:version) { "1.2.3" }
let(:prerelease) { true }
let(:download_path) { "/some/path" }
it "returns the correct command" do
expect(build_command).to eq("#{prefix} | sudo bash -s -- -p -v \"1.2.3\" -d \"/some/path\"")
it "includes the version" do
command = described_class.ps_command("chef", "1.2.3", "stable")
expect(command).to include %|-version '1.2.3'|
end
end
end

View File

@ -30,13 +30,18 @@ their purpose.
- `installer_download_path` (string) - The path where the Chef installer will be
downloaded to. This option is only honored if the `install` attribute is
`true` or `"force"`. The default value is to use the path provided by Chef's
Omnibus installer, which varies between releases.
Omnibus installer, which varies between releases. This value has no effect on
Windows because Chef's omnibus installer lacks the option on Windows.
- `log_level` (string) - The Chef log level. See the Chef docs for acceptable
values.
- `prerelease` (boolean) - Install a prerelease version of Chef. The default
value is false.
- `product` (string) - The name of the Chef product to install. The default
value is "chef", which corresponds to the Chef Client. You can also specify
"chefdk", which will install the Chef Development Kit.
- `channel` (string) - The release channel from which to pull the Chef Client
or the Chef Development Kit. The default value is `"current"`.
- `version` (string) - The version of Chef to install on the guest. If Chef is
already installed on the system, the installed version is compared with the