This bug (invalid method call) hasn't been caught by unit tests because
Vagrant::Plugin::V2::Config catches all invalid/bad configuration calls
and save them for generating error messages during the "validate" stage.
This way, the `ask_sudo_pass=(value)` method was not interrupted and the
`@ask_become_pass` attribute was (surprisingly) correctly set (allowing
the related unit tests to pass).
In order to avoid similar problem to happen again, the deprecation
message output is now fully verified.
- Keep the Programming Errors with corresponding Exception class and
en.yml message template. Fix the alphabetical order in errors.rb by
the way.
- Fix English wording in the documentation and en.yml messages
- Use StandardError for unknown error rescuing.
Thanks @chrisroberts!
Vagrant will verify that the current Ansible version does support the
requested compatibility mode (only applicable if not "auto", of course).
As mentioned in the documentation, there is no sanity checks between
`version` option and `compatibility_mode` option.
With this change, the host-based provisioner is also improved to
execute only once the "ansible" command (and store the gathered
information for multiple usages like version requirement and
compatibility checks). On the other hand, the guest-based provisioner
can still potentially execute "ansible" twice (once in the
AnsibleInstalled cap, and via "gather_ansible_version" function via
Base::set_compatibility_mode).
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.
With this change, it is now possible to get rid of many deprecation
messages successively introduced in Ansible 1.9, and 2.0. More
interesting, the generated inventory will contain the recommended
variable names (e.g. `ansible_host` instead of `ansible_ssh_host`)
when the compatibility mode is set to '2.0'.
Details:
- Add `compatibility_mode` option to control the Ansible parameters
format to be used. The value corresponds to the minimal version
supported. For the moment, possible values are '1.8' (corresponding to
Vagrant's former behaviour) or '2.0'.
Note that a dynamic inventory generated in compatibility mode '2.0'
is not supported by Ansible 1.x. On the other hand, Ansible 2.x so far
supports inventory format generated by the compatibility mode '1.8'.
- Add compatibility mode auto-detection, based on the available Ansible
version. This is the default behaviour in order to bring a maximum of
user friendliness. The drawback of this approach is to let potential
compatibility breaking risks, for `ansible` provisioner setups that
already integrate Ansible 2.x **AND** rely on the existence of
the generated `_ssh` variable names. Thanks to the vagrant warnings
(and its release notes), I argue that it is worth to offer
auto-detection by default, which offers a sweet transition to most
users.
- Add `become`, `become_user` and `ask_become_pass` options and their
backwards compatible aliases. The legacy options are now deprecated.
Note that we intentionally didn't provide a '1.9' compatibility mode,
as it would add extra-complexity for practically no added-value.
To my knowledge, the Ansible 2.x series haven't introduced yet any major
changes or deprecations that would motivate to introduce a higher
version compatibility mode (to be confirmed/verified).
Resolve GH-6570
Still Pending:
- Optimization: Reduce the number of `ansible` command executions.
Currently two exec calls will be performed when the compatibility
mode auto-detection is enabled (i.e. by default). We could make the
provisioner a little bit smarter to only execute `ansible` only once
in any situation (by combining "presence" and "version" checks).
- User-friendliness: Add better validator on `compatibility_mode`
option, and shows a warning or an error instead of the silent
fallback on the auto-detection modus.
- Test coverage: All the added behaviours are not fully covered yet.
The patterns "all" is a special keyword that target all hosts in the
inventory. Therefore it makes sense to accept "all:vars" as a group
variable name. Note that "*:vars" pattern is not valid in an Ansible
inventory.
See http://docs.ansible.com/ansible/latest/intro_patterns.html#patternsFix#7730
While neither the FreeBSD provisioner nor the SUSE provisioner support
installing Ansible using pip their ansible_install methods still get
called with that fourth argument. The result being these errors when
Vagrant tries to install Ansible.
/opt/vagrant/embedded/gems/gems/vagrant-1.9.5/plugins/provisioners/ansible/cap/guest/freebsd/ansible_install.rb:10:in `ansible_install': wrong number of arguments (4 for 3) (ArgumentError)
/opt/vagrant/embedded/gems/gems/vagrant-1.9.5/plugins/provisioners/ansible/cap/guest/suse/ansible_install.rb:9:in `ansible_install': wrong number of arguments (4 for 3) (ArgumentError)
The Arch provider, it too without pip support, already catches the
pip_args argument this way.
With the introduction of `pip_args` option, you can easily extend the
`:pip` installation mode behaviour. But some interesting/advanced usages
are still not possible because of the auto-generated parts ("ansible"
package, version selection, and the `--upgrade` flag).
By adding this "pip_args_only" install mode, it will be for instance
possible to:
- install unofficial releases, like release candidates published at
https://releases.ansible.com/
- install more pip packages (e.g. via a `requirements.txt` file), with
hash validation, etc.
Note that there is no config validation that requires `pip_args` option
to be defined when the :pip_args_only mode is selected. This would be
more elegant, and user friendly to raise a configuration error, but this
can wait. At least, running with an empty `pip_args` won't lead to any
command crash, since the rather dummy "pip install" shows an helper
notice and terminates with a zero (0) exit code.
This change is thought as a complement to the changes originally
proposed in pull request GH-8170.
With this new option, it is now possible to pass additional arguments to
pip command when the `install_mode` is "pip".
(@gildegoma reworded the original commit message of pull request GH-8170)
With this new option defined, the `ansible-galaxy` and
`ansible-playbook` commands generated by the Ansible provisioners will
be executed with the ANSIBLE_CONFIG environment variable set
accordingly.
Resolve GH-7195
This commit also fix the following open issues:
- Implement the pending RSpec examples about path existence checks
performed by the ansible (remote) provisioner.
- In verbose mode, the ansible remote provisioner now correctly displays
the Ansible Galaxy parameters ("role_file" and "roles_path") with
single quotes (which is safer for potential copy-paste usage).
Additional Notes:
- Test coverage for `ansible_local` provisioner is still not
implemented. See GH-6633.
- Test coverage for galaxy from host is not implemented yet (due to
general issue with mocking both command executions, see
https://github.com/mitchellh/vagrant/pull/6529#r45278451
- Remove `ansible-galaxy` detection, since this command was introduced
in Ansible 1.4.2 (December 2013). Checking for `ansible-playbook`
presence should therefore be enough for any "modern" Ansible setup.
- Look for the command defined by the new `playbook_command` option.
Related to GH-7881 and GH-7536
Note that error messages were not adapted, and only mention
a generic "Ansible Software" when executed commands are failing.
We assume that people using the `playbook_command` option are
advanced users that will know all the components to be considered.
The ansible-playbook command is currently hardcoded for the ansible and
ansible_local provisioners. This patch adds the config option
playbook_command to allow the user to change the command.
- Honour `ssh.proxy_command` setting (even when the Docker provider is
used via a proxy host). Silly configurations may lead to silly
behaviors, but let's apply the settings...
- Remove condition on `provider_config.connect_via_ssh`, which is
a provider specific parameter (from vagrant-libvirt provider).
- Add a simple unit test
This commit include the following changes:
- systematically set ANSIBLE_ROLES_PATH environment variable when
galaxy_roles_path is defined.
- slightly refactor to introduce the concept of "provisioning working
directory" (possible usage in the future for resolving GH-7195)
- fix a bug in ansible-galaxy execution by the ansible_local provisioner
if the paths contains blank characters.
Fix#7269
These changes have been validated against the following guest systems:
- Debian 7 and 8
- Ubuntu 12.04, 14.04 and 16.04
- Fedora 21 and 23
- CentOS 7
- OracleLinux 7
- Scientific Linux 7
At the moment, the pip setup (via get-pip.py script) is not working for
RHEL6-like systems (CentOS 6.6, OracleLinux 6.5, Scientific Linux 6),
because Python 2.6 has been deprecated and is no longer supported by
Python core team. I consider this limitation with low priority in
Vagrant context.
The `:pip` install_mode is currently not implemented for the following
platforms:
- OpenSUSE
- ArchLinux
- FreeBSD
Known Issue: By using get-pip.py script, any previous pip installation
will be most probably overrided. This could be an issue for Python
developers who would prefer to keep their base box setup untouched. In
future iteration, it could be possible to choose to reinstall/upgrade
pip or not. issue for Python developers who would prefer to keep their
base box setup untouched. In future iteration, it could be possible to
choose to reinstall/upgrade pip or not.
Resolve GH-6654
Resolve GH-7167 as the `version` option is now considered to select the
version of Ansible to be installed.
With this change, the presence of Ansible configuration files (like
playbook file, inventory path, galaxy role file, etc.) is no longer
performed by the `config` classes, but by the `provisioner` classes
(at the beginning of the provision command).
This change fixes several issues:
- Resolve#6984 as `provision` method are only executed when remote
(ssh) communication with the guest machine is possible.
- Resolve#6763 in a better way than 4e451c6 initially did.
- Improve the general provisioner speed since the `config` checks are
actually triggered by many vagrant actions (e.g. `destroy`,...), and
can also be triggered multiple times during a vagrant run (e.g. on
callback request made by the machine provider).
Unlike the former `config`-based checks, the provision action won't
collect all the invalid options, but only report the first invalid
option found and abort the execution.
Some unit tests were not implemented yet to save my scarce "open source
contribution time" for other important issues, but they should be done
at last via GH-6633.
Changes:
- Add "config" unit tests for `ansible_local` (guest)
- Share some "config" examples between both ansible provisioners
- Move `config_host.rb` specific examples to `config/host.rb`
- Add a requirement to "../helpers" in `config/guest.rb` in order to be
able to run the related unit tests
References:
- This is the first part of GH-6633 resolution
- This change is a handy prerequisite for GH-6570
Not addressed yet:
- FIXME (guest.rb): Some test-double stubs are currently not working as
expected, and the related checks are commented out for the moment
(no idea why, but this is not urgent to be fixed because of GH-7335
rejection. See also GH-6984)
- FIXME (shared.rb): The guest-based config should actually NOT return
an error when the extra_vars file cannot be found, but only display a
a warning (similarly to the changes done for GH-6763, see 4e451c6)
This fixes a fairly large tempfile leak. Vagrant uses a template
renderer to write network configuration files locally to disk. Then,
that temporarily file is uploaded to the remote host and moved into
place. Since Vagrant is such a short-lived process, GC never came along
and cleaned up those tempfiles, resulting in many temporary files being
created through regular Vagrant usage.
The Util::Tempfile class uses a block to ensure the temporary file is
deleted when the block finishes. This API required small tweaks to the
usage, but provides more safety to ensure the files are deleted.
With this change, the `raw_arguments` and `raw_ssh_args` options are:
- STILL automatically converted as an Array when they are set a String
(no behaviour change)
- rejected if they are not of Array data type otherwise
Additional Notes:
- the 'as_array' tiny helper has been removed since it was no longer
used.
- there is for now no deeper validation (i.e. verifying that the Array
elements are only *String* objects)
With cb80286a4a, the helper function
stringify_ansible_playbook_command was also applied on the
`raw_arguments` content, which is not wanted. Given that users have used
the `raw_arguments` option as a workaround to avoid the bug GH-6726,
this new change ensure that any `--extra-vars` option passed as a raw
argument won't be additonally enquoted by the ansible_local
provisioner.
This change also improves the ansible remote provisioner verbose output,
but has no impact on its behaviour, which was already correct.
Note that this refactoring introduces some code duplications that are not
very elegant (see ansible_playbook_command_for_shell_execution in
host.rb and execute_ansible_playbook_from_host in base.rb). I hope we
can find a better implementation later, but it is good enough for now
since all these parts are covered by corresponding unit tests (the
`ansible_local` stuff being tested via the verbose output of the ansible
remote provisioner).