51 votes

Exécuter `apt-get update` avant d'installer d'autres paquets avec Puppet

J'essaie de créer un module marionnette qui automatise l'installation de zend server CE, ce n'est pas important ici, mais les étapes sont les suivantes

  1. mettre à jour /etc/apt/source.list
  2. télécharger la clé de repos via wget
  3. faites apt-get update
  4. faites apt-get install zend-server-ce-5.2

J'ai init.pp archivo

class zendserverce {

# https://github.com/puppetlabs/puppetlabs-stdlib
file_line { 'debian_package':
    path => '/etc/apt/sources.list',
    line => 'deb http://repos.zend.com/zend-server/deb server non-free'
}

exec { "wget http://repos.zend.com/zend.key -O- |apt-key add -":
    path => ["/usr/bin", "/usr/sbin"]
}

exec { "apt-get update":
    command => "/usr/bin/apt-get update",
    onlyif  => "/bin/sh -c '[ ! -f /var/cache/apt/pkgcache.bin ] || /usr/bin/find /etc/apt/* -cnewer /var/cache/apt/pkgcache.bin | /bin/grep . > /dev/null'",
}

package { "zend-server-ce-php-5.2":
    ensure => "latest"
}

}

Il semble que puppet exécute les commandes dans un ordre différent de celui dont j'ai besoin. Y a-t-il un moyen de lui dire de les exécuter dans l'ordre que je souhaite ?

La sortie d'un tel extrait est

  [0;36mnotice: /Stage[main]/Mc/Package[mc]/ensure: ensure changed 'purged' to 'latest'[0m
  [1;35merr: /Stage[main]/Zendserverce/Package[zend-server-ce-php-5.2]/ensure: change from purged to latest failed: Could not update: Execution of '/usr/bin/apt-get -q -y -o DPkg::Options::=--force-confold install zend-server-ce-php-5.2' returned 100: Reading package lists...
  Building dependency tree...
  Reading state information...
  E: Couldn't find package zend-server-ce-php-5.2 at /tmp/vagrant-puppet/modules 0/zendserverce/manifests/init.pp:28[0m
  [0;36mnotice: /Stage[main]/Zendserverce/Exec[wget http://repos.zend.com/zend.key -O- |apt-key add -]/returns: executed successfully[0m
  [0;36mnotice: /Stage[main]/Zendserverce/File_line[debian_package]/ensure: created[0m
  [0;36mnotice: Finished catalog run in 6.75 seconds[0m

C'est écrit : Impossible de trouver le paquet zend-server-ce-php-5.2

Quelqu'un peut-il me dire ce qui ne va pas ?

0 votes

0 votes

Je signale juste un problème secondaire : votre apt-get update ne sera exécuté qu'une seule fois et ne s'exécutera plus jamais tant que les fichiers dans le répertoire /etc/apt/** ne sont pas modifiées. Cela peut conduire à des informations de mise à jour périmées lors de l'installation d'autres paquets. Vous pouvez également ajouter cette vérification bash qui renvoie vrai si l'apt-get update a été exécuté il y a plus d'un jour : [[ $(( $(date +%s) - $(stat -c %Z /var/cache/apt/pkgcache.bin) )) -gt $(( 24 * 60 * 60 )) ]]

0 votes

Un petit mot sur votre apt-key add invocation. Récupérer quelque chose via HTTP, puis le transmettre à apt-key vous rend vulnérable à une variété d'attaques de sécurité, y compris MITM. Il semblerait que zend ne propose pas d'accès HTTPS à cette clé, ce qui est dommage. Si vous pouvez vérifier manuellement la clé, il serait plus sûr de l'envoyer via une autre méthode, peut-être file { ... }

101voto

DrDol Points 1491

Depuis la version 2.6.0 de Puppet, une nouvelle fonctionnalité "syntaxe des relations" a été mise en place. introduit .

Un exemple dans Puppet 2.6.0 et plus ressemblerait à ceci :

exec { "apt-update":
    command => "/usr/bin/apt-get update"
}

Exec["apt-update"] -> Package <| |>

Chaque fois qu'une commande de paquetage est exécutée, la dépendance (dans notre cas, 'apt-update') sera déclenchée en premier. Vous pouvez même définir des chaînes plus longues.

1 votes

En fait, j'utilise des étapes pour cela, mais je dois admettre que cette astuce est plutôt astucieuse !

12 votes

Merci, c'était super utile ! Pour les autres novices comme moi qui s'interrogent sur cette dernière ligne : "<|" est la notation du collecteur, voir docs.puppetlabs.com/puppet/3/reference/lang_collectors.html

2 votes

Cela semble se produire à chaque mise à jour de la marionnette, qu'une installation de paquet soit nécessaire ou non. Existe-t-il un moyen de resserrer ce processus afin qu'apt-get update ne s'exécute que lorsqu'un paquet est absent du système ?

51voto

czervik Points 1290

Vous devez spécifier les relations de dépendance. L'approche la plus simple et la plus propre consiste à utiliser le paramètre require qui est disponible pour tous les types de ressources.

package { "zend-server-ce-php-5.2":
  ensure  => latest,
  require  => Exec['apt-get update'],
}

etc.

5 votes

Je lis docs.puppetlabs.com/guides/language_guide.html#run-stages et puppet fournit des stages pour que vous puissiez spécifier explicitement l'ordre d'exécution. Les étapes d'exécution ont été ajoutées dans la version 2.6.0 de Puppet, vous avez maintenant la possibilité de spécifier un nombre quelconque d'étapes qui fournissent une autre méthode pour contrôler l'ordre de gestion des ressources dans Puppet.

1 votes

C'est peut-être "le plus facile/le plus propre", mais est-il maintenable ? Si l'Exec devait changer, il faudrait alors revenir en arrière et remplacer chaque déclaration, le point étant que cette approche n'est pas référentielle.

3 votes

@BrandonCook Alors vous pouvez donner un nouveau nom à votre exécuteur. exec{update: command => "apt-get update"} puis le référencer comme Exec[update] .

13voto

Pavel Železný Points 71

J'ai essayé la variante précédente mais elle ne fonctionne pas pour moi sur Ubuntu 10.04

Finalement, j'ai préparé le script suivant, qui exécute la mise à jour chaque fois que le dépôt est plus vieux qu'une semaine :

exec { 'apt-get update':
    command => "/usr/bin/apt-get update",
    onlyif => "/bin/bash -c 'exit $(( $(( $(date +%s) - $(stat -c %Y /var/lib/apt/lists/$( ls /var/lib/apt/lists/ -tr1|tail -1 )) )) <= 604800 ))'"
}

J'espère que cela vous aidera.

12voto

joerx Points 525

Je préfère mettre apt-upgrade dans une étape séparée s'exécutant avant l'étape principale, afin de ne pas avoir à câbler les dépendances. Vérifiez ici : http://docs.puppetlabs.com/puppet/2.7/reference/lang_run_stages.html .

Un exemple simple serait le suivant. Il implique que vous ayez une classe séparée pour effectuer l'apt-update proprement dit :

stage { "init": before  => Stage["main"] }

class {"apt-update": 
  stage => init, 
  apt_mirror => $apt_mirror 
}

Consultez mon exemple de boîte LAMPP sur github pour voir comment les pièces s'assemblent : https://github.com/joerx/vagrant-lampp

Note : soyez prudent avec apt-upgrade, car certaines boîtes de base sont cassées par des choses comme les mises à jour du noyau.

1 votes

Génial. C'est une fonctionnalité assez géniale que je ne connaissais pas. Merci de la partager.

0 votes

Link est mort comme une souris.

0 votes

J'ai corrigé le lien, mais la partie pertinente du manifeste est maintenant commentée. Vous pouvez quand même la voir. Rien n'est statique ...

4voto

Brandon Cook Points 419

Dans Puppet 3, cela peut être fait par réaliser des ressources virtuelles en utilisant des collecteurs de ressources

# so you don't have to fully qualify paths to binaries
Exec { path => ['/usr/bin'] }    

# virtual resource
@exec { 'sudo apt-get update':
   tag => foo_update
}

# realize resource. filter by arbitrary "foo_update"
# tag and relate it to all Package resources
Exec <| tag == foo_update |> -> Package <| |>

0 votes

Cela ne fonctionne pas pour moi sous 3.2.4, à moins que je ne change pour des chemins entièrement qualifiés. @exec { '/usr/bin/sudo /usr/bin/apt-get update ...

0 votes

Bon appel, j'ai testé cela il y a longtemps et j'ai ajouté Exec { path => ['/usr/bin'] }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X