38

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

sudo apt-get build-dep python-lxml

我知道我可以安装apt puppet 模块,所以我可以使用:

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

但我找不到任何关于从脚本安装模块以及如何包含/需要它的参考。在我看来,木偶文档仅指从命令行木偶工具安装

我也尝试做类似的事情:

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 install从命令行)apt:builddep工作正常。但我需要 puppet 来处理模块下载和安装。其他一些解决方法也适用于基本用例,但不会回答我的主要问题。

4

8 回答 8

66

我也遇到了这个问题。诀窍是在 puppet 配置程序运行之前使用 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 配置器的模块文件夹来安装模块的原因是因为我不想下载我要下载的模块的所有依赖项在我的源代码管理中使用和存储所有这些模块。运行这两个命令会产生 5 个依赖项,否则它们会位于我的 git 存储库中占用空间。

于 2013-07-25T17:35:54.003 回答
14

这是我为使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
于 2014-02-14T06:38:57.477 回答
8

我使用类似于@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
于 2014-01-14T03:40:57.970 回答
4

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

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

Vagrant 会注意将此目录挂载到正确的位置。所以不需要在节点上运行除了 puppet 本身之外的脚本。

于 2014-06-17T15:23:55.540 回答
2

受 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')
于 2014-07-29T06:39:05.553 回答
2

@brain_bacon's strategy worked almost perfectly for me, with one small caveat - if the module already exists, then the provisioning script fails, halting the provisioning process. The following adjustment fixed this:

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
于 2014-11-12T12:48:16.243 回答
1

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

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

有关详细信息,请参阅文档

于 2013-07-07T05:45:45.927 回答
1

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

#!/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 盒子。

于 2017-04-01T20:13:07.707 回答