diff --git a/plugins/provisioners/ansible/cap/guest/posix/ansible_installed.rb b/plugins/provisioners/ansible/cap/guest/posix/ansible_installed.rb index 329eab8a9..3c7f623de 100644 --- a/plugins/provisioners/ansible/cap/guest/posix/ansible_installed.rb +++ b/plugins/provisioners/ansible/cap/guest/posix/ansible_installed.rb @@ -10,8 +10,8 @@ module VagrantPlugins def self.ansible_installed(machine, version) command = 'test -x "$(command -v ansible)"' - if !version.empty? - command << "&& ansible --version | grep 'ansible #{version}'" + unless version.empty? + command << "&& [[ $(python -c \"import importlib.metadata; print(importlib.metadata.version('ansible'))\") == \"#{version}\" ]]" end machine.communicate.test command, sudo: false diff --git a/plugins/provisioners/ansible/provisioner/guest.rb b/plugins/provisioners/ansible/provisioner/guest.rb index 1474b837b..e81bceaf5 100644 --- a/plugins/provisioners/ansible/provisioner/guest.rb +++ b/plugins/provisioners/ansible/provisioner/guest.rb @@ -75,7 +75,7 @@ module VagrantPlugins raw_output = "" result = @machine.communicate.execute( - "ansible --version", + "python -c \"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\"", error_class: Ansible::Errors::AnsibleNotFoundOnGuest, error_key: :ansible_not_found_on_guest) do |type, output| if type == :stdout && output.lines[0] diff --git a/plugins/provisioners/ansible/provisioner/host.rb b/plugins/provisioners/ansible/provisioner/host.rb index f2a57133c..c2b9ddea4 100644 --- a/plugins/provisioners/ansible/provisioner/host.rb +++ b/plugins/provisioners/ansible/provisioner/host.rb @@ -108,8 +108,9 @@ module VagrantPlugins end def gather_ansible_version - raw_output = "" - command = %w(ansible --version) + raw_output = '' + command = ['python', '-c', + "\"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\""] command << { notify: [:stdout, :stderr] diff --git a/test/unit/plugins/provisioners/ansible/provisioner_test.rb b/test/unit/plugins/provisioners/ansible/provisioner_test.rb index fdf9aa67e..d41d52af9 100644 --- a/test/unit/plugins/provisioners/ansible/provisioner_test.rb +++ b/test/unit/plugins/provisioners/ansible/provisioner_test.rb @@ -71,12 +71,14 @@ VF # Class methods for code reuse across examples # - def self.it_should_check_ansible_version() - it "execute 'ansible --version' before executing 'ansible-playbook'" do - expect(Vagrant::Util::Subprocess).to receive(:execute). - once.with('ansible', '--version', { :notify => [:stdout, :stderr] }) - expect(Vagrant::Util::Subprocess).to receive(:execute). - once.with('ansible-playbook', any_args) + def self.it_should_check_ansible_version + it "execute 'Python ansible version check before executing 'ansible-playbook'" do + expect(Vagrant::Util::Subprocess).to receive(:execute) + .once.with('python', '-c', "\"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\"", { notify: %i[ + stdout stderr + ] }) + expect(Vagrant::Util::Subprocess).to receive(:execute) + .once.with('ansible-playbook', any_args) end end @@ -326,6 +328,7 @@ VF "2.x.y.z": VagrantPlugins::Ansible::COMPATIBILITY_MODE_V2_0, "4.3.2.1": VagrantPlugins::Ansible::COMPATIBILITY_MODE_V2_0, "[core 2.11.0]": VagrantPlugins::Ansible::COMPATIBILITY_MODE_V2_0, + "7.1.0": VagrantPlugins::Ansible::COMPATIBILITY_MODE_V2_0 } valid_versions.each_pair do |ansible_version, mode| describe "and ansible version #{ansible_version}" do @@ -347,7 +350,7 @@ VF "2.9.2.1", ] invalid_versions.each do |unknown_ansible_version| - describe "and `ansible --version` returning '#{unknown_ansible_version}'" do + describe "and `ansible version check returning '#{unknown_ansible_version}'" do before do allow(subject).to receive(:gather_ansible_version).and_return(unknown_ansible_version) end @@ -1044,10 +1047,11 @@ VF expect {subject.provision}.to raise_error(VagrantPlugins::Ansible::Errors::AnsibleCommandFailed) end - it "execute three commands: ansible --version, ansible-galaxy, and ansible-playbook" do + it 'execute three commands: Python ansible version check, ansible-galaxy, and ansible-playbook' do expect(Vagrant::Util::Subprocess).to receive(:execute) .once - .with('ansible', '--version', { :notify => [:stdout, :stderr] }) + .with('python', '-c', + "\"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\"", { notify: %i[stdout stderr] }) .and_return(default_execute_result) expect(Vagrant::Util::Subprocess).to receive(:execute) .once