plugins/provisioners/ansible/provisioner/base.rb in vagrant-unbundled-1.9.8.1 vs plugins/provisioners/ansible/provisioner/base.rb in vagrant-unbundled-2.0.0.1
- old
+ new
@@ -1,5 +1,6 @@
+require_relative "../constants"
require_relative "../errors"
require_relative "../helpers"
module VagrantPlugins
module Ansible
@@ -12,21 +13,86 @@
class Base < Vagrant.plugin("2", :provisioner)
RANGE_PATTERN = %r{(?:\[[a-z]:[a-z]\]|\[[0-9]+?:[0-9]+?\])}.freeze
+ ANSIBLE_PARAMETER_NAMES = {
+ Ansible::COMPATIBILITY_MODE_V1_8 => {
+ ansible_host: "ansible_ssh_host",
+ ansible_password: "ansible_ssh_pass",
+ ansible_port: "ansible_ssh_port",
+ ansible_user: "ansible_ssh_user",
+ ask_become_pass: "ask-sudo-pass",
+ become: "sudo",
+ become_user: "sudo-user",
+ },
+ Ansible::COMPATIBILITY_MODE_V2_0 => {
+ ansible_host: "ansible_host",
+ ansible_password: "ansible_password",
+ ansible_port: "ansible_port",
+ ansible_user: "ansible_user",
+ ask_become_pass: "ask-become-pass",
+ become: "become",
+ become_user: "become-user",
+ }
+ }
+
protected
def initialize(machine, config)
super
+ @control_machine = nil
@command_arguments = []
@environment_variables = {}
@inventory_machines = {}
@inventory_path = nil
+
+ @gathered_version_stdout = nil
+ @gathered_version_major = nil
+ @gathered_version = nil
end
+ def set_and_check_compatibility_mode
+ begin
+ set_gathered_ansible_version(gather_ansible_version)
+ rescue StandardError => e
+ # Nothing to do here, as the fallback on safe compatibility_mode is done below
+ @logger.error("Error while gathering the ansible version: #{e.to_s}")
+ end
+
+ if @gathered_version_major
+ if config.compatibility_mode == Ansible::COMPATIBILITY_MODE_AUTO
+ detect_compatibility_mode
+ elsif @gathered_version_major.to_i < 2 && config.compatibility_mode == Ansible::COMPATIBILITY_MODE_V2_0
+ # A better version comparator will be needed
+ # when more compatibility modes come... but so far let's keep it simple!
+ raise Ansible::Errors::AnsibleCompatibilityModeConflict,
+ ansible_version: @gathered_version,
+ system: @control_machine,
+ compatibility_mode: config.compatibility_mode
+ end
+ end
+
+ if config.compatibility_mode == Ansible::COMPATIBILITY_MODE_AUTO
+ config.compatibility_mode = Ansible::SAFE_COMPATIBILITY_MODE
+
+ @machine.env.ui.warn(I18n.t("vagrant.provisioners.ansible.compatibility_mode_not_detected",
+ compatibility_mode: config.compatibility_mode,
+ gathered_version: @gathered_version_stdout) +
+ "\n")
+ end
+
+ unless Ansible::COMPATIBILITY_MODES.slice(1..-1).include?(config.compatibility_mode)
+ raise Ansible::Errors::AnsibleProgrammingError,
+ message: "The config.compatibility_mode must be correctly set at this stage!",
+ details: "config.compatibility_mode: '#{config.compatibility_mode}'"
+ end
+
+ @lexicon = ANSIBLE_PARAMETER_NAMES[config.compatibility_mode]
+ end
+
def check_files_existence
check_path_is_a_file(config.playbook, :playbook)
check_path_exists(config.inventory_path, :inventory_path) if config.inventory_path
check_path_is_a_file(config.config_file, :config_file) if config.config_file
@@ -68,11 +134,11 @@
shell_args = []
@command_arguments.each do |arg|
if arg =~ /(--start-at-task|--limit)=(.+)/
shell_args << %Q(#{$1}="#{$2}")
elsif arg =~ /(--extra-vars)=(.+)/
- shell_args << %Q(%s="%s") % [$1, $2.gsub('\\', '\\\\\\').gsub('"', %Q(\\"))]
+ shell_args << %Q(%s=%s) % [$1, $2.shellescape]
else
shell_args << arg
end
end
@@ -95,12 +161,12 @@
@command_arguments << "--limit=#{@machine.name}"
end
@command_arguments << "--inventory-file=#{inventory_path}"
@command_arguments << "--extra-vars=#{extra_vars_argument}" if config.extra_vars
- @command_arguments << "--sudo" if config.sudo
- @command_arguments << "--sudo-user=#{config.sudo_user}" if config.sudo_user
+ @command_arguments << "--#{@lexicon[:become]}" if config.become
+ @command_arguments << "--#{@lexicon[:become_user]}=#{config.become_user}" if config.become_user
@command_arguments << "#{verbosity_argument}" if verbosity_is_enabled?
@command_arguments << "--vault-password-file=#{config.vault_password_file}" if config.vault_password_file
@command_arguments << "--tags=#{Helpers::as_list_argument(config.tags)}" if config.tags
@command_arguments << "--skip-tags=#{Helpers::as_list_argument(config.skip_tags)}" if config.skip_tags
@command_arguments << "--start-at-task=#{config.start_at_task}" if config.start_at_task
@@ -146,11 +212,17 @@
if !vars
vars = config.host_vars[machine_name.to_s]
end
s = nil
if vars.is_a?(Hash)
- s = vars.each.collect{ |k, v| "#{k}=#{v}" }.join(" ")
+ s = vars.each.collect {
+ |k, v|
+ if v.is_a?(String) && v.include?(' ') && !v.match(/^('|")[^'"]+('|")$/)
+ v = %Q('#{v}')
+ end
+ "#{k}=#{v}"
+ }.join(" ")
elsif vars.is_a?(Array)
s = vars.join(" ")
elsif vars.is_a?(String)
s = vars
end
@@ -226,11 +298,11 @@
inventory_groups += "#{gm}\n" if defined_groups.include?(gm)
end
end
group_vars.each_pair do |gname, gmembers|
- if defined_groups.include?(gname.sub(/:vars$/, ""))
+ if defined_groups.include?(gname.sub(/:vars$/, "")) || gname == "all:vars"
inventory_groups += "\n[#{gname}]\n" + gmembers.join("\n") + "\n"
end
end
return inventory_groups
@@ -280,9 +352,47 @@
if config.verbose.to_s =~ /^-?(v+)$/
"-#{$+}"
else
# safe default, in case input strays
'-v'
+ end
+ end
+
+ private
+
+ def detect_compatibility_mode
+ if !@gathered_version_major || config.compatibility_mode != Ansible::COMPATIBILITY_MODE_AUTO
+ raise Ansible::Errors::AnsibleProgrammingError,
+ message: "The detect_compatibility_mode() function shouldn't have been called!",
+ details: %Q(config.compatibility_mode: '#{config.compatibility_mode}'
+gathered version major number: '#{@gathered_version_major}'
+gathered version stdout version:
+#{@gathered_version_stdout})
+ end
+
+ if @gathered_version_major.to_i <= 1
+ config.compatibility_mode = Ansible::COMPATIBILITY_MODE_V1_8
+ else
+ config.compatibility_mode = Ansible::COMPATIBILITY_MODE_V2_0
+ end
+
+ @machine.env.ui.warn(I18n.t("vagrant.provisioners.ansible.compatibility_mode_warning",
+ compatibility_mode: config.compatibility_mode,
+ ansible_version: @gathered_version) +
+ "\n")
+ end
+
+ def set_gathered_ansible_version(stdout_output)
+ @gathered_version_stdout = stdout_output
+ if !@gathered_version_stdout.empty?
+ first_line = @gathered_version_stdout.lines[0]
+ ansible_version_pattern = first_line.match(/(^ansible\s+)(.+)$/)
+ if ansible_version_pattern
+ _, @gathered_version, _ = ansible_version_pattern.captures
+ if @gathered_version
+ @gathered_version_major = @gathered_version.match(/^(\d)\..+$/).captures[0].to_i
+ end
+ end
end
end
end
end