From a241e79fc40a26fdb69d4868959e2f5c4dc22512 Mon Sep 17 00:00:00 2001 From: Taru Garg Date: Thu, 7 Aug 2025 20:07:19 +0530 Subject: [PATCH] Fix Ansible Install capability for RHEL like system with version >= 10 (#13701) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On RHEL-like systems with major version >= 10, the current Ansible installation logic incorrectly parses the version from rpm -E %dist. This is because the current inline sed command that only extracts the first character of the version string—so for version 10, it extracts only 1, resulting in an incorrect download URL. --- .../cap/guest/redhat/ansible_install.rb | 11 +++- .../cap/guest/redhat/ansible_install_test.rb | 64 +++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 test/unit/plugins/provisioners/ansible/cap/guest/redhat/ansible_install_test.rb diff --git a/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb b/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb index fd475040b..c2bad76b2 100644 --- a/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb +++ b/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb @@ -31,7 +31,7 @@ module VagrantPlugins 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' + machine.communicate.sudo "sudo rpm -i #{ansible_epel_download_url(machine)}" end machine.communicate.sudo "#{rpm_package_manager} -y --enablerepo=epel install ansible" end @@ -67,6 +67,15 @@ module VagrantPlugins }) end + def self.ansible_epel_download_url(machine) + dist = "" + machine.communicate.execute("rpm -E %dist") do |type, data| + dist << data if type == :stdout + end + dist.strip! + dist_major_version = dist.match(/.*el(\d+).*/)&.captures&.first + "https://dl.fedoraproject.org/pub/epel/epel-release-latest-#{dist_major_version}.noarch.rpm" + end end end end diff --git a/test/unit/plugins/provisioners/ansible/cap/guest/redhat/ansible_install_test.rb b/test/unit/plugins/provisioners/ansible/cap/guest/redhat/ansible_install_test.rb new file mode 100644 index 000000000..55512dc10 --- /dev/null +++ b/test/unit/plugins/provisioners/ansible/cap/guest/redhat/ansible_install_test.rb @@ -0,0 +1,64 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: BUSL-1.1 + +require_relative "../../../../../../base" + +require Vagrant.source_root.join("plugins/provisioners/ansible/cap/guest/redhat/ansible_install") + +describe VagrantPlugins::Ansible::Cap::Guest::RedHat::AnsibleInstall do + include_context "unit" + + subject { VagrantPlugins::Ansible::Cap::Guest::RedHat::AnsibleInstall } + + let(:iso_env) do + env = isolated_environment + env.vagrantfile("") + env.create_vagrant_env + end + let(:machine) { iso_env.machine(iso_env.machine_names[0], :dummy) } + let(:communicator) { double("comm") } + let(:dist) { ".el8" } + let(:epel) { 1 } + + before do + allow(machine).to receive(:communicate).and_return(communicator) + allow(communicator).to receive(:execute).with("rpm -E %dist").and_yield(:stdout, dist) + end + + describe "#ansible_epel_download_url" do + it "returns the correct EPEL download URL for RHEL-like versions below 10" do + expect(subject.ansible_epel_download_url(machine)).to eq("https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm") + end + + context "for RHEL-like versions 10 and above" do + let(:dist) { ".el10" } + it "returns the correct EPEL download URL" do + out = subject.ansible_epel_download_url(machine) + expect(out).to eq("https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm") + end + end + end + + describe "#ansible_rpm_install" do + before do + expect(communicator).to receive(:test).with("/usr/bin/which -s dnf").and_return(false) + expect(communicator).to receive(:execute).with("yum repolist epel | grep -q epel", error_check: false).and_return(epel) + expect(communicator).to receive(:sudo).with("yum -y --enablerepo=epel install ansible") + end + + it "installs ansible package, when epel is not installed" do + expect(communicator).to receive(:sudo).with("sudo rpm -i https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm") + subject.ansible_rpm_install(machine) + end + + context "when the EPEL repository is already installed" do + let(:epel) { 0 } + it "installs ansible package" do + expect(communicator).to_not receive(:sudo).with("sudo rpm -i https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm") + subject.ansible_rpm_install(machine) + end + end + + end + +end