web-dev-qa-db-fra.com

Installer un module marionnette à partir d'un script manifeste

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

35
alonisser

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.

63
brain_bacon

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
14
wtanaka.com

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
7
Juan Carlos Méndez

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.

4
sebastianwagner

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')
2
nybon

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.

1

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
1
mistertim

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 .

1
Gergo Erdosi