Reputation: 1251
I have this scenario in Vagrant where I wanted to patch how the ansible is being installed on RHEL 8 (because of certain issues with absence of packages missing due to repository setup) using ansible_local plugin. So here's the thing. Instead, I wanted to use pip3 (though I know I can use pip using ansible_local module but still it errs after that due to absence of certain repository so I figure out a way to fix it).
In my Vagrantfile, I have these lines as such,
.....
node.vm.provision "ansible_local" do |ansible|
ansible.playbook = ansible_playbook
ansible.verbose = true
ansible.install = true
## Actually this line doesn't suffice my problem since it still errs as pip requires other packages. Please check the *.rb file below
if i == 100
ansible.install_mode = "pip"
ansible.version = "2.9"
#ansible.ansible_rpm_install = Foo
end
end
...
.....
But because using pip still fails, so I end up changing the file /opt/vagrant/embedded/gems/2.2.9/gems/vagrant-2.2.9/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb
and what I did is this way,
cap/guest/redhat/ansible_install.rb
require_relative "../facts"
require_relative "../pip/pip"
module VagrantPlugins
module Ansible
module Cap
module Guest
module RedHat
module AnsibleInstall
def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd = "")
case install_mode
when :pip
pip_setup machine, pip_install_cmd
Pip::pip_install machine, "ansible", ansible_version, pip_args, true
when :pip_args_only
pip_setup machine, pip_install_cmd
Pip::pip_install machine, "", "", pip_args, false
else
// My added part as a quick fix/solution
if machine.config.vm.box == "generic/rhel8"
ansible_rpm_install_rhel8 machine
elsif
ansible_rpm_install machine
end
end
end
private
def self.ansible_rpm_install(machine)
rpm_package_manager = Facts::rpm_package_manager(machine)
epel = machine.communicate.execute "#{rpm_package_manager} repolist epel | grep -q epel", error_check: false
if epel != 0
machine.communicate.sudo 'sudo rpm -i https://dl.fedoraproject.org/pub/epel/epel-release-latest-`rpm -E %dist | sed -n \'s/.*el\([0-9]\).*/\1/p\'`.noarch.rpm'
end
machine.communicate.sudo "#{rpm_package_manager} -y --enablerepo=epel install ansible"
end
def self.pip_setup(machine, pip_install_cmd = "")
rpm_package_manager = Facts::rpm_package_manager(machine)
machine.communicate.sudo("#{rpm_package_manager} -y install curl gcc libffi-devel openssl-devel python-crypto python-devel python-setuptools")
Pip::get_pip machine, pip_install_cmd
end
def self.pip_setup(machine, pip_install_cmd = "")
rpm_package_manager = Facts::rpm_package_manager(machine)
machine.communicate.sudo("#{rpm_package_manager} -y install curl gcc libffi-devel openssl-devel python-crypto python-devel python-setuptools")
Pip::get_pip machine, pip_install_cmd
end
// My added part as a quick fix/solution
def self.ansible_rpm_install_rhel8(machine)
rpm_package_manager = Facts::rpm_package_manager(machine)
epel = machine.communicate.execute "#{rpm_package_manager} repolist epel | grep -q epel", error_check: false
if epel != 0
machine.communicate.sudo 'sudo rpm -i https://dl.fedoraproject.org/pub/epel/epel-release-latest-`rpm -E %dist | sed -n \'s/.*el\([0-9]\).*/\1/p\'`.noarch.rpm'
end
machine.communicate.sudo "dnf -y update; dnf -y install python3 python3-pip; pip3 install ansible"
end
end
end
end
end
end
end
So I added a method self.ansible_rpm_install_rhel8(machine)
and did an if..elsif
as a solution when box name is "generic/rhel8"
. This works perfect actually on my end. However, I don't like this approach i.e. changing the file /opt/vagrant/embedded/gems/2.2.9/gems/vagrant-2.2.9/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb
because once it changes or version upgrades, this will be gone. Is there any better way that I can just do this only inside Vagrantfile such that perhaps overriding or extending the class itself? I have no idea how to do this.
Any ideas are welcome.
Thank you!
Upvotes: 1
Views: 189
Reputation: 6404
You can use multiple provisioning sections next one another which will be executed in the order as you defined them in your Vagrantfile
.
Instead of patching a plugin, try to prepare your ansible execution accordingly.
Before executing the provisioning part for ansible, execute a shell provisioning as follows:
Vagrant.configure("2") do |node|
# ...
node.vm.provision :shell, path: "fix_repo_and_add_packages.sh"
node.vm.provision "ansible_local" do |ansible|
ansible.playbook = ansible_playbook
ansible.verbose = true
ansible.install = true
## Actually this line doesn't suffice my problem since it still errs as pip requires other packages. Please check the *.rb file below
if i == 100
ansible.install_mode = "pip"
ansible.version = "2.9"
#ansible.ansible_rpm_install = Foo
end
end
end
Your fix_repo_and_add_packages.sh
contains the setup of the missing repos and here you can add packages as well.
For more information about shell provisioning, you can find in the doc
Upvotes: 2