【问题标题】:How to extend a vagrant plugin through Vagrantfile without changing the .rb file?如何在不更改 .rb 文件的情况下通过 Vagrantfile 扩展 vagrant 插件?
【发布时间】:2021-02-25 04:59:04
【问题描述】:

我在 Vagrant 中有一个场景,我想使用 ansible_local 插件修补如何在 RHEL 8 上安装 ansible(由于存储库设置导致缺少软件包的某些问题)。事情就是这样。相反,我想使用 pip3(虽然我知道我可以使用 ansible_local 模块来使用 pip,但由于缺少某些存储库,之后它仍然会出错,所以我想办法修复它)。

在我的 Vagrantfile 中,我有这些行,

.....
      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
...
.....

但是因为使用 pip 仍然失败,所以我最终更改了文件/opt/vagrant/embedded/gems/2.2.9/gems/vagrant-2.2.9/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb 而我所做的就是这样,


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

所以我添加了一个方法self.ansible_rpm_install_rhel8(machine),并在盒子名称为"generic/rhel8" 时做了一个if..elsif 作为解决方案。这实际上对我来说很完美。但是,我不喜欢这种方法,即更改文件/opt/vagrant/embedded/gems/2.2.9/gems/vagrant-2.2.9/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb,因为一旦它更改或版本升级,它就会消失。有没有更好的方法可以只在 Vagrantfile 中执行此操作,以便可能覆盖或扩展类本身?我不知道该怎么做。

欢迎提出任何想法。

谢谢!

【问题讨论】:

  • 您可以使用多个配置。在执行 ansible 之前,您是否尝试过 shell 配置?在那里,您可以预先配置(添加、更新...)存储库并根据需要添加一些包。
  • 嗨@Mark,感谢您添加。啊,你能举例说明如何做到这一点吗?尽管不清楚您的想法到底是什么,但我可能能够理解您...谢谢您的意见。

标签: ansible vagrant vagrant-plugin rhel8


【解决方案1】:

您可以使用多个配置部分,这些部分将按照您在Vagrantfile 中定义的顺序执行。

不要修补插件,而是尝试相应地准备您的 ansible 执行。

在执行 ansible 的配置部分之前,执行 shell 配置,如下所示:

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

您的fix_repo_and_add_packages.sh 包含缺少的存储库的设置,您也可以在此处添加包。

有关 shell 配置的更多信息,您可以在doc 中找到

【讨论】:

  • 谢谢@Mark。它实际上是这样工作的。对于一些想要修复或覆盖问题的用户,如果您有多个节点和/或各种操作系统要支持但其他操作系统版本存在问题,请确保您以这种方式包含 if/else 条件。
猜你喜欢
  • 1970-01-01
  • 2011-09-18
  • 2021-04-20
  • 2013-05-20
  • 2017-03-22
  • 2020-07-14
  • 2011-01-31
  • 1970-01-01
  • 2017-07-06
相关资源
最近更新 更多