provisioners/ansible: Move `version` to common options
Before this change, only the ansible_local provisioner supported this option (for ansible version requirement, and pip installation). Now, the ansible host-based provisioner can also require a exact ansible version. Resolve #8914 Note: this has been added as part of #6570 resolution, since the introduction of the `compatibility_mode` auto-detection made both provisioners made capable to detect ansible version. Pending: optimize the code to avoid duplicated executions of "ansible --version" command.
This commit is contained in:
parent
15e74e264d
commit
8c0df3d046
|
@ -28,6 +28,7 @@ module VagrantPlugins
|
|||
attr_accessor :tags
|
||||
attr_accessor :vault_password_file
|
||||
attr_accessor :verbose
|
||||
attr_accessor :version
|
||||
|
||||
#
|
||||
# Deprecated options
|
||||
|
@ -64,6 +65,7 @@ module VagrantPlugins
|
|||
@tags = UNSET_VALUE
|
||||
@vault_password_file = UNSET_VALUE
|
||||
@verbose = UNSET_VALUE
|
||||
@version = UNSET_VALUE
|
||||
end
|
||||
|
||||
def finalize!
|
||||
|
@ -87,6 +89,7 @@ module VagrantPlugins
|
|||
@tags = nil if @tags == UNSET_VALUE
|
||||
@vault_password_file = nil if @vault_password_file == UNSET_VALUE
|
||||
@verbose = false if @verbose == UNSET_VALUE
|
||||
@version = "" if @version == UNSET_VALUE
|
||||
end
|
||||
|
||||
# Just like the normal configuration "validate" method except that
|
||||
|
|
|
@ -11,7 +11,6 @@ module VagrantPlugins
|
|||
attr_accessor :install
|
||||
attr_accessor :install_mode
|
||||
attr_accessor :pip_args
|
||||
attr_accessor :version
|
||||
|
||||
def initialize
|
||||
super
|
||||
|
@ -21,7 +20,6 @@ module VagrantPlugins
|
|||
@pip_args = UNSET_VALUE
|
||||
@provisioning_path = UNSET_VALUE
|
||||
@tmp_path = UNSET_VALUE
|
||||
@version = UNSET_VALUE
|
||||
end
|
||||
|
||||
def finalize!
|
||||
|
@ -32,7 +30,6 @@ module VagrantPlugins
|
|||
@pip_args = "" if @pip_args == UNSET_VALUE
|
||||
@provisioning_path = "/vagrant" if provisioning_path == UNSET_VALUE
|
||||
@tmp_path = "/tmp/vagrant-ansible" if tmp_path == UNSET_VALUE
|
||||
@version = "" if @version == UNSET_VALUE
|
||||
end
|
||||
|
||||
def validate(machine)
|
||||
|
|
|
@ -23,8 +23,8 @@ module VagrantPlugins
|
|||
error_key(:cannot_support_pip_install)
|
||||
end
|
||||
|
||||
class AnsibleVersionNotFoundOnGuest < AnsibleError
|
||||
error_key(:ansible_version_not_found_on_guest)
|
||||
class AnsibleVersionMismatch < AnsibleError
|
||||
error_key(:ansible_version_mismatch)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -65,7 +65,7 @@ module VagrantPlugins
|
|||
if (!config.version.empty? &&
|
||||
config.version.to_s.to_sym != :latest &&
|
||||
!@machine.guest.capability(:ansible_installed, config.version))
|
||||
raise Ansible::Errors::AnsibleVersionNotFoundOnGuest, required_version: config.version.to_s
|
||||
raise Ansible::Errors::AnsibleVersionMismatch, system: "guest", required_version: config.version.to_s
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ module VagrantPlugins
|
|||
@ssh_info = @machine.ssh_info
|
||||
|
||||
warn_for_unsupported_platform
|
||||
check_required_ansible_version unless config.version.empty?
|
||||
check_files_existence
|
||||
set_compatibility_mode
|
||||
|
||||
|
@ -36,6 +37,19 @@ module VagrantPlugins
|
|||
end
|
||||
end
|
||||
|
||||
def check_required_ansible_version
|
||||
if config.version.to_s.to_sym == :latest
|
||||
@logger.debug("The :latest version requirement is not supported (yet) by the host-based provisioner")
|
||||
return
|
||||
end
|
||||
|
||||
@logger.info("Checking for Ansible version on Vagrant host...")
|
||||
found_version = gather_ansible_version
|
||||
if (!found_version || "ansible #{config.version}\n" != found_version.lines[0])
|
||||
raise Ansible::Errors::AnsibleVersionMismatch, system: "host", required_version: config.version.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def prepare_command_arguments
|
||||
# Connect with native OpenSSH client
|
||||
# Other modes (e.g. paramiko) are not officially supported,
|
||||
|
|
|
@ -2364,11 +2364,11 @@ en:
|
|||
to contribute back support. Thank you!
|
||||
|
||||
https://github.com/mitchellh/vagrant
|
||||
ansible_version_not_found_on_guest: |-
|
||||
The requested Ansible version (%{required_version}) was not found on the guest.
|
||||
Please check the ansible installation on your guest system,
|
||||
ansible_version_mismatch: |-
|
||||
The requested Ansible version (%{required_version}) was not found on the %{system}.
|
||||
Please check the Ansible installation on your Vagrant %{system} system,
|
||||
or adapt the `version` option of this provisioner in your Vagrantfile.
|
||||
See https://docs.vagrantup.com/v2/provisioning/ansible_local.html
|
||||
See https://docs.vagrantup.com/v2/provisioning/ansible_common.html#version
|
||||
for more information.
|
||||
config_file_not_found: |-
|
||||
`%{config_option}` does not exist on the %{system}: %{path}
|
||||
|
|
|
@ -16,7 +16,8 @@ describe VagrantPlugins::Ansible::Config::Guest do
|
|||
let(:existing_file) { "this/path/is/a/stub" }
|
||||
|
||||
it "supports a list of options" do
|
||||
supported_options = %w( become
|
||||
supported_options = %w(
|
||||
become
|
||||
become_user
|
||||
compatibility_mode
|
||||
config_file
|
||||
|
@ -43,7 +44,8 @@ describe VagrantPlugins::Ansible::Config::Guest do
|
|||
tmp_path
|
||||
vault_password_file
|
||||
verbose
|
||||
version )
|
||||
version
|
||||
)
|
||||
|
||||
expect(get_provisioner_option_names(described_class)).to eql(supported_options)
|
||||
end
|
||||
|
@ -58,7 +60,6 @@ describe VagrantPlugins::Ansible::Config::Guest do
|
|||
expect(subject.install_mode).to eql(:default)
|
||||
expect(subject.provisioning_path).to eql("/vagrant")
|
||||
expect(subject.tmp_path).to eql("/tmp/vagrant-ansible")
|
||||
expect(subject.version).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@ describe VagrantPlugins::Ansible::Config::Host, :skip_windows => true do
|
|||
let(:existing_file) { File.expand_path(__FILE__) }
|
||||
|
||||
it "supports a list of options" do
|
||||
supported_options = %w( ask_become_pass
|
||||
supported_options = %w(
|
||||
ask_become_pass
|
||||
ask_sudo_pass
|
||||
ask_vault_pass
|
||||
become
|
||||
|
@ -40,7 +41,9 @@ describe VagrantPlugins::Ansible::Config::Host, :skip_windows => true do
|
|||
sudo_user
|
||||
tags
|
||||
vault_password_file
|
||||
verbose )
|
||||
verbose
|
||||
version
|
||||
)
|
||||
|
||||
expect(get_provisioner_option_names(described_class)).to eql(supported_options)
|
||||
end
|
||||
|
|
|
@ -25,6 +25,7 @@ shared_examples_for 'options shared by both Ansible provisioners' do
|
|||
expect(subject.tags).to be_nil
|
||||
expect(subject.vault_password_file).to be_nil
|
||||
expect(subject.verbose).to be(false)
|
||||
expect(subject.version).to be_empty
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -947,6 +947,46 @@ VF
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
context "with version option set" do
|
||||
before do
|
||||
config.version = "2.3.4.5"
|
||||
end
|
||||
|
||||
describe "and the installed ansible version is correct" do
|
||||
before do
|
||||
allow(subject).to receive(:gather_ansible_version).and_return("ansible #{config.version}\n...\n")
|
||||
end
|
||||
|
||||
it "executes ansible-playbook command" do
|
||||
expect(Vagrant::Util::Subprocess).to receive(:execute).with('ansible-playbook', any_args).and_return(default_execute_result)
|
||||
end
|
||||
end
|
||||
|
||||
describe "and there is an ansible version mismatch" do
|
||||
before do
|
||||
allow(subject).to receive(:gather_ansible_version).and_return("ansible 1.9.6\n...\n")
|
||||
end
|
||||
|
||||
it "raises an error about the ansible version mismatch", skip_before: true, skip_after: true do
|
||||
config.finalize!
|
||||
expect {subject.provision}.to raise_error(VagrantPlugins::Ansible::Errors::AnsibleVersionMismatch)
|
||||
end
|
||||
end
|
||||
|
||||
describe "and the installed ansible version cannot be detected" do
|
||||
before do
|
||||
allow(subject).to receive(:gather_ansible_version).and_return(nil)
|
||||
end
|
||||
|
||||
it "raises an error about the ansible version mismatch", skip_before: true, skip_after: true do
|
||||
config.finalize!
|
||||
expect {subject.provision}.to raise_error(VagrantPlugins::Ansible::Errors::AnsibleVersionMismatch)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: add more tests, now that we know how to deal with multiple Subprocess stub executions
|
||||
describe "with galaxy support" do
|
||||
|
||||
before do
|
||||
|
|
|
@ -42,7 +42,7 @@ Some of these options are for advanced usage only and should not be used unless
|
|||
|
||||
<div class="alert alert-warning">
|
||||
<strong>Attention:</strong>
|
||||
Vagrant doesn't perform any validation between the `compatibility_mode` value and the value of the ansible_local [`version`](/docs/provisioning/ansible_local.html#version) option.
|
||||
Vagrant doesn't perform any validation between the `compatibility_mode` value and the value of the [`version`](#version) option.
|
||||
</div>
|
||||
|
||||
- `config_file` (string) - The path to an [Ansible Configuration file](https://docs.ansible.com/intro_configuration.html).
|
||||
|
@ -185,3 +185,16 @@ Some of these options are for advanced usage only and should not be used unless
|
|||
Examples: `true` (equivalent to `v`), `-vvv` (equivalent to `vvv`), `vvvv`.
|
||||
|
||||
Note that when the `verbose` option is enabled, the `ansible-playbook` command used by Vagrant will be displayed.
|
||||
|
||||
- `version` (string) - The expected Ansible version.
|
||||
|
||||
This option is disabled by default.
|
||||
|
||||
When an Ansible version is defined (e.g. `"2.1.6.0"`), the Ansible provisioner will be executed only if Ansible is installed at the requested version.
|
||||
|
||||
When this option is set to `"latest"`, no version check is applied.
|
||||
|
||||
<div class="alert alert-info">
|
||||
<strong>Tip:</strong>
|
||||
With the `ansible_local` provisioner, it is currently possible to use this option to specify which version of Ansible must be automatically installed, but <strong>only</strong> in combination with the [**`install_mode`**](ansible_local.html#install_mode) set to <strong>`:pip`</strong>.
|
||||
</div>
|
||||
|
|
|
@ -62,8 +62,8 @@ This section lists the _specific_ options for the Ansible Local provisioner. In
|
|||
Vagrant will try to install (or upgrade) Ansible when one of these conditions are met:
|
||||
|
||||
- Ansible is not installed (or cannot be found).
|
||||
- The `version` option is set to `"latest"`.
|
||||
- The current Ansible version does not correspond to the `version` option.
|
||||
- The [`version`](/docs/provisioning/ansible_common.html#version) option is set to `"latest"`.
|
||||
- The current Ansible version does not correspond to the [`version`](/docs/provisioning/ansible_common.html#version) option.
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<strong>Attention:</strong>
|
||||
|
@ -76,7 +76,7 @@ This section lists the _specific_ options for the Ansible Local provisioner. In
|
|||
- On Ubuntu-like systems, the latest Ansible release is installed from the `ppa:ansible/ansible` repository.
|
||||
- On RedHat-like systems, the latest Ansible release is installed from the [EPEL](http://fedoraproject.org/wiki/EPEL) repository.
|
||||
|
||||
- `:pip`: Ansible is installed from [PyPI](https://pypi.python.org/pypi) with [pip](https://pip.pypa.io) package installer. With this mode, Vagrant will systematically try to [install the latest pip version](https://pip.pypa.io/en/stable/installing/#installing-with-get-pip-py). With the `:pip` mode you can optionally install a specific Ansible release by setting the [`version`](#version) option.
|
||||
- `:pip`: Ansible is installed from [PyPI](https://pypi.python.org/pypi) with [pip](https://pip.pypa.io) package installer. With this mode, Vagrant will systematically try to [install the latest pip version](https://pip.pypa.io/en/stable/installing/#installing-with-get-pip-py). With the `:pip` mode you can optionally install a specific Ansible release by setting the [`version`](/docs/provisioning/ansible_common.html#version) option.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -141,19 +141,6 @@ This section lists the _specific_ options for the Ansible Local provisioner. In
|
|||
|
||||
The default value is `/tmp/vagrant-ansible`
|
||||
|
||||
- `version` (string) - The expected Ansible version.
|
||||
|
||||
This option is disabled by default.
|
||||
|
||||
When an Ansible version is defined (e.g. `"1.8.2"`), the Ansible local provisioner will be executed only if Ansible is installed at the requested version.
|
||||
|
||||
When this option is set to `"latest"`, no version check is applied.
|
||||
|
||||
<div class="alert alert-info">
|
||||
<strong>Tip:</strong>
|
||||
It is currently possible to use this option to specify which version of Ansible must be automatically installed, but <strong>only</strong> in combination with the `install_mode` set to <strong>`:pip`</strong>.
|
||||
</div>
|
||||
|
||||
## Tips and Tricks
|
||||
|
||||
### Ansible Parallel Execution from a Guest
|
||||
|
|
Loading…
Reference in New Issue