J'utilise marionnette pour provisionner une machine virtuelle vagabonde (basée sur Ubuntu). Dans mon script, je dois:
Sudo apt-get build-dep python-lxml
Je sais que je peux installer le apt
module marionnette pour pouvoir utiliser:
apt::builddep { 'python-lxml': }
Mais je ne trouve aucune référence sur l'installation d'un module à partir du script et comment l'inclure/l'exiger. Il me semble que les documents de marionnettes se réfèrent uniquement à installation à partir de l'outil de marionnettes en ligne de commande
J'ai aussi essayé de faire quelque chose comme:
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";
}
Mais la marionnette est sortie avec une erreur à ce sujet. Et aussi:
exec{"install apt module":
command => "puppet module install puppetlabs/apt"
}
class { 'apt':
require => Exec["install apt module"]}
include apt
apt::builddep { 'python-imaging':
}
mais j'ai could not find declared class apt at..
des idées? directions? Je sais que je manque quelque chose d'évident mais je ne peux pas le comprendre.
EDIT: Si je pré-installe (avec puppet module install
depuis la ligne de commande) le apt:builddep
fonctionne très bien. Mais j'ai besoin d'une marionnette pour gérer le téléchargement et l'installation du module . Certains des autres contournements fonctionnent également pour le cas d'utilisation de base, mais ne répondront pas à ma question principale.
J'ai également rencontré ce problème. L'astuce consiste à télécharger les modules à l'aide d'une commande Shell vagabonde avant l'exécution du provisionneur de marionnettes.
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
L'ordre est important ici, et puisque le provisionneur de marionnettes n'a pas exécuté le dossier/etc/puppet/modules n'existe pas encore.
La raison pour laquelle j'ai décidé, comme alonisser, d'installer les modules à l'aide de l'outil module de marionnettes au lieu d'utiliser un dossier de modules avec le provisionneur de marionnettes vagabond, c'est parce que je ne voulais pas avoir à télécharger toutes les dépendances des modules que j'allais utiliser et stocker tous ces modules dans mon contrôle de code source. L'exécution de ces deux commandes entraîne 5 dépendances qui, sinon, resteraient dans mon référentiel git prenant de l'espace.
Voici ce que j'ai fait pour faire le puppet module install
commande exécutée au plus une fois:
$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
J'utilise une approche similaire à @brain_bacon - la complication supplémentaire que j'avais était qu'en plus des modules pré-emballés comme puppetlabs/nodejs j'avais besoin de modules locaux par rapport à mon Vagrantfile. Je ne voulais pas archiver les modules pré-packagés dans le cadre de mon référentiel, ni utiliser de sous-modules git en raison des problèmes signalés par @Igor Popov.
Enfin, la solution que j'ai choisie était d'utiliser un script Shell pour télécharger les modules, mais en forçant leur chemin dans le répertoire partagé entre le Vagrant VM et l'hôte, et en utilisant .gitignore pour éviter que ce chemin ne soit sous contrôle de source.
Pour être clair, avec cet arbre:
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
Sur .gitignore
J'ai ajouté
/puppet/modules/mysql
Sur 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
Vous pouvez installer des modules de marionnettes sur la machine hôte dans votre vagrantdir
:
puppet module --modulepath=./puppet/modules/ install puppetlabs/mysql
Vagrant prend soin de monter ce répertoire au bon endroit. Il n'est donc pas nécessaire d'exécuter des scripts autres que la marionnette elle-même sur le nœud.
Inspiré par la réponse de wtanaka.com, j'ai implémenté une solution comme ci-dessous qui je pense est beaucoup plus lisible.
1) créez un nouveau fichier Ruby appelé 'puppet_deps.rb' dans le même dossier que Vagrantfile avec le code ci-dessous:
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) Dans votre Vagrantfile, vous pouvez charger ce fichier Ruby et l'utiliser pour spécifier la dépendance de la marionnette:
# 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')
En utilisant les réponses de cette question, j'ai créé ce script:
#!/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
Ensuite, vous pouvez l'utiliser à partir de votre Vagrantfile
comme ceci:
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(" ")
Il supprime la marionnette de vm si la version est inférieure à 3.8.7
, puis installe puppet 3.8.7
, puis installe tous les modules.
Cela ne fonctionnerait probablement que sur les boîtes debian/ubuntu.
La stratégie de @ brain_bacon a fonctionné presque parfaitement pour moi, avec une petite mise en garde - si le module existe déjà, alors le script de provisioning échoue, interrompant le processus de provisioning. L'ajustement suivant a résolu ce problème:
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
Vous pouvez créer un répertoire pour les modules et ajouter le module apt
que vous avez téléchargé depuis la forge. Alors il sera modules/apt/*
. Vous pouvez ensuite spécifier ce répertoire de module dans Vagrantfile
(module_path
est relatif à Vagrantfile
):
Vagrant.configure("2") do |config|
config.vm.provision :puppet do |puppet|
puppet.module_path = "modules"
end
end
Pour plus d'informations, consultez la documentation .