从清单脚本安装puppet模块

时间:2013-07-06 23:45:08

标签: vagrant puppet

我正在使用puppet来配置一个流浪汉(基于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";
}

但是傀儡退出了这个错误。还有:

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正常工作。 但我需要木偶来处理模块下载和安装。其他一些工作也适用于基本用例,但不会回答我的主要问题。

8 个答案:

答案 0 :(得分:62)

我也遇到了这个问题。诀窍是在木偶配置器运行之前使用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

订单在这里很重要,因为木偶供应商还没有运行文件夹/ etc / puppet / modules还不存在。

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

答案 1 :(得分:13)

以下是我最多只运行一次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

答案 2 :(得分:7)

我使用类似于@brain_bacon的方法 - 我的额外复杂性是除了预先打包的模块,如puppetlabs / nodejs,我需要相对于我的Vagrantfile的本地模块。我不想将预先打包的模块作为我的存储库的一部分进行检查,也不要使用git子模块,因为@Igor Popov指出了这些问题。

最后,我选择的解决方案是使用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

答案 3 :(得分:4)

您可以在vagrantdir

中的主机上安装puppet模块
puppet module --modulepath=./puppet/modules/ install puppetlabs/mysql

Vagrant负责将此目录安装到正确的位置。 因此,不需要在节点上运行除puppet之外的脚本。

答案 4 :(得分: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')

答案 5 :(得分:1)

您可以为模块创建目录,并添加从福奇下载的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

答案 6 :(得分:1)

@ 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 :(得分:0)

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

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