【问题标题】:Installing a puppet module from a manifest script从清单脚本安装 puppet 模块
【发布时间】:2013-07-04 16:33:41
【问题描述】:

我正在使用 puppet 来配置一个 vagrant(基于 ubuntu)的虚拟机。 在我的脚本中,我需要:

sudo apt-get build-dep python-lxml

我知道我可以安装 apt puppet module 以便我可以使用:

apt::builddep { 'python-lxml': }

但我找不到任何关于从脚本安装模块以及如何包含/需要它的参考。在我看来,木偶文档仅指installing from the command line puppet tool

我也尝试过这样做:

define build_dep($pkgname){
    exec {
    "builddepend_$pkgname":
    commmand => "sudo apt-get build-dep $pkgname";
    }
}
build_dep{
    "python-imaging":
    pkgname => "python-imaging";

    "python-lxml":
    pkgname => "python-lxml";
}

但是 puppet 退出时出现错误。还有:

exec{"install apt module":

    command => "puppet module install puppetlabs/apt"
}

class { 'apt':
        require => Exec["install apt module"]}
include apt

apt::builddep { 'python-imaging':
 }

但得到could not find declared class apt at..

有什么想法吗?方向?我知道我遗漏了一些明显的东西,但无法弄清楚。

编辑:如果我预先安装(使用命令行中的puppet module installapt:builddep 工作正常。 但我需要 puppet 来处理模块下载和安装。其他一些解决方法也适用于基本用例,但不会回答我的主要问题。

【问题讨论】:

    标签: vagrant puppet


    【解决方案1】:

    我也遇到了这个问题。诀窍是在 puppet provisioner 运行之前使用 vagrant shell 命令下载模块。

    config.vm.provision :shell do |shell|
      shell.inline = "mkdir -p /etc/puppet/modules;
                      puppet module install puppetlabs/nodejs;
                      puppet module install puppetlabs/apache"
    end
    
    config.vm.provision :puppet do |puppet|
      puppet.manifests_path = "puppet/manifests"
      puppet.manifest_file = "site.pp"
    end
    

    这里的顺序很重要,因为 puppet 供应商还没有运行文件夹 /etc/puppet/modules 还不存在。

    我决定像 alonisser 一样,使用 puppet 模块工具安装模块,而不是使用带有 vagrant puppet provisioner 的模块文件夹,因为我不想下载所有模块的依赖项打算在我的源代码管理中使用和存储所有这些模块。运行这两个命令会产生 5 个依赖项,否则这些依赖项会在我的 git 存储库中占用空间。

    【讨论】:

    • 接受了答案,因为它似乎(部分)有效并且它类似于我所走的路。试图微调 puppet 的执行顺序让我受了太多打击。我实际上去使用git submodule update --init 来处理(预定义)模块依赖关系。并运行它 pre-puppet\vagrant
    • 它一直有效,直到您在同一虚拟机上再次运行配置步骤...然后它失败并显示:“模块已安装”。
    • --force 不会安装依赖模块
    • 我确实通过将 shell 命令包装为 true 来绕过多个配置,例如(puppet module install puppetlabs/apache; true) 但如果模块由于其他原因无法安装,这可能会产生意想不到的后果。
    • 为了避免第二个条款的错误或使用--force的必要性,你可以执行(puppet module list |grep puppetlabs-nodejs ) || (mkdir -p /etc/puppet/modules; puppet module install puppetlabs/nodejs)之类的东西(在cmets中没有回车,抱歉)
    【解决方案2】:

    为了使puppet module install 命令最多运行一次,我做了以下操作:

    $script = <<EOF
    mkdir -p /etc/puppet/modules
    (puppet module list | grep puppetlabs-mysql) ||
       puppet module install -v 2.1.0 puppetlabs/mysql
    EOF
    
    Vagrant::Config.run do |config|
       config.vm.provision :shell, :inline => $script
    

    【讨论】:

      【解决方案3】:

      我使用类似于@brain_bacon 的方法 - 我遇到的额外复杂情况是,除了像 puppetlabs/nodejs 这样的预打包模块之外,我还需要相对于我的 Vagrantfile 的本地模块。由于@Igor Popov 指出的问题,我不想将预打包的模块作为我的存储库的一部分签入,也不想使用 git 子模块。

      最后我选择的解决方案是使用 shell 脚本下载模块,但强制它们的路径进入 Vagrant VM 和主机之间的共享目录,并使用 .gitignore 来避免该路径受到源代码控制。

      要清楚,用这棵树:

      jcmendez$ tree
      .
      ├── README.md
      ├── Vagrantfile
      ├── files
      ├── puppet
      │   ├── manifests
      │   │   └── init.pp
      │   └── modules
      │       ├── misc
      │       │   └── manifests
      │       │       └── init.pp
      │       ├── mysql
         ...
      │       └── wordpress
      │           ├── files
      │           │   ├── wordpress-db.sql
      │           │   ├── wp-config.php
      │           │   └── wp-tests-config.php
      │           └── manifests
      │               └── init.pp
      └── wordpress
      

      .gitignore我添加了

        /puppet/modules/mysql
      

      开启Vagrantfile

        config.vm.provision :shell do |shell|
          shell.inline = "puppet module install puppetlabs/mysql --force --modulepath '/vagrant/puppet/modules'"
        end
      
        config.vm.provision :puppet do |puppet|
          puppet.manifests_path = 'puppet/manifests'
          puppet.module_path = 'puppet/modules'
          puppet.manifest_file  = "init.pp"
          puppet.options="--verbose --debug"
        end
      

      【讨论】:

      • 我按照你的方式进行(除了我正在尝试 puppetlab-apache 安装):内联 shell 安装并得到“/tmp/vagrant 的未知函数 validate_bool”。当未安装其中一个依赖项时出现。你是如何安装 apache 的?
      • @DiH - 你是对的,确保通读每个包的所有依赖项,因为当依赖项不满足时出现的错误消息有点神秘。不过,我没有安装 apache2……我们的设置中有 nginx。
      【解决方案4】:

      您可以在vagrantdir 中的主机上安装 puppet 模块:

      puppet module --modulepath=./puppet/modules/ install puppetlabs/mysql
      

      Vagrant 会小心地将这个目录挂载到正确的位置。 所以不需要在节点上运行除了 puppet 本身以外的脚本。

      【讨论】:

      【解决方案5】:

      受 wtanaka.com 的回答启发,我实现了一个类似下面的解决方案,我认为它更具可读性。

      1) 在与 Vagrantfile 相同的文件夹下创建一个名为“puppet_deps.rb”的新 ruby​​ 文件,代码如下:

      def install_dep(name, version, install_dir = nil)
          install_dir ||= '/etc/puppet/modules'
          "mkdir -p #{install_dir} && (puppet module list | grep #{name}) || puppet module install -v #{version} #{name}"
      end
      

      2) 在你的 Vagrantfile 中,你可以加载这个 ruby​​ 文件并使用它来指定 puppet 依赖:

      # on top of your Vagrantfile
      require './puppet_deps'
      ...
      ...
      # in your vm definition, use a shell provisioning this:
      config.vm.provision :shell, :inline => install_dep('puppetlabs-firewall', '1.1.3')
      config.vm.provision :shell, :inline => install_dep('puppetlabs-stdlib', '4.3.2')
      

      【讨论】:

        【解决方案6】:

        @brain_bacon 的策略对我来说几乎是完美的,但有一点需要注意 - 如果模块已经存在,那么配置脚本会失败,从而停止配置过程。以下调整解决了这个问题:

        config.vm.provision :shell, :run => "always" do |shell|
          shell.inline = %{
            mkdir -p /etc/puppet/modules;
            function install_module {
              folder=`echo $1 | sed s/.*-//`
              if [ ! -d /etc/puppet/modules/$folder ]; then
                puppet module install $1
              fi
            }
            install_module stdlib
            install_module apt
            install_module ruby
          }
        end
        

        【讨论】:

          【解决方案7】:

          您可以为模块创建一个目录并添加您从 forge 下载的 apt 模块。所以它将是modules/apt/*。然后你可以在Vagrantfile中指定这个模块目录(module_path是相对于Vagrantfile):

          Vagrant.configure("2") do |config|
            config.vm.provision :puppet do |puppet|
              puppet.module_path = "modules"
            end
          end
          

          有关详细信息,请参阅documentation

          【讨论】:

          • 这并没有回答如何从脚本自动下载和安装模块的问题,无需预下载等。
          • 您为什么要这样做? Puppet 脚本通常包含在 vagrant 设置中。以后它们甚至不会在您的 VM 上可用(至少在使用默认 puppet 配置时不可用)。
          【解决方案8】:

          使用这个问题的答案我创建了这个脚本:

          #!/bin/bash
          
          function install_module {
             IFS=':' read module version <<< "$1"
             if (puppet module list | grep $module ) >/dev/null; then
              echo "Module $module is already installed"
             else
                  if [ -z "$version" ]; then
                      puppet module install $module
                  else 
                  puppet module install -v $version $module
              fi
              fi  
          }
          
          if dpkg --compare-versions `puppet --version` "lt" 3.8.7; then
              sudo apt-get remove --purge -y puppet
              sudo apt-get -y autoremove
          fi
          
          if which puppet >/dev/null; then
              echo "Puppet is already installed"
          else
              echo "Installing puppet"
              wget https://apt.puppetlabs.com/puppetlabs-release-trusty.deb
              sudo dpkg -i puppetlabs-release-trusty.deb
              sudo apt-get update
              sudo apt-get install -y puppet=3.8.7*
              mkdir -p /etc/puppet/modules
          fi
          
          for var in "$@" 
          do
              install_module "$var"
          done
          

          然后你可以像这样从Vagrantfile 使用它:

          puppet_modules = [
              'puppetlabs-stdlib:4.16.0',
              'puppetlabs-apt:2.3.0',
              'puppet-nodejs:2.3.0'
              ]
          
          config.vm.provision "shell", path: "puppet/scripts/puppet.sh", args: puppet_modules.join(" ")
          

          如果版本低于3.8.7,它会从vm中删除puppet,然后安装puppet 3.8.7,然后安装所有模块。

          它可能只适用于 debian/ubuntu 机器。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-05-18
            • 2014-09-06
            • 1970-01-01
            • 2013-12-09
            • 1970-01-01
            • 2015-02-12
            • 1970-01-01
            相关资源
            最近更新 更多