web-dev-qa-db-fra.com

y a-t-il des itérateurs et des boucles dans la marionnette?

Lorsque je définis (?) Une ressource, par exemple pour assurer la structure dir, y a-t-il des boucles disponibles?

Comme ça:

  for X in [app1,app2] do:
    file { '/opt/app/' + X:
      ensure => directory,
      owner  => 'root',
      group  => 'root',
      mode   => '0644',
    }

J'ai des dizaines de répertoires et je suis vraiment fatigué de le déclarer en marionnette. Il faudrait 15 LOC de bash.

Des idées?

35
user425720

Les anciennes versions de la langue des marionnettes ne prennent pas en charge les boucles.

Mais vous pouvez utiliser un tableau au lieu d'une simple chaîne pour le titre et déclarer plusieurs ressources en même temps avec les mêmes paramètres:

$b = '/opt/app'
file { [ "$b/app1", "$b/app2" ]:
  ensure => directory,
  owner  => 'root',
  group  => 'root',
  mode   => 0644,
}

Vous pouvez également déclarer de nombreuses ressources du même type avec des paramètres différents en terminant chaque ressource par un ;, ce qui est un peu plus compact que de répéter les file et les {le sable }s:

file {
  [ "$b/app1", "$b/app2" ]:
    ensure => directory,
    owner  => 'root',
    group  => 'root',
    mode   => 0755;
  [ "$b/app1/secret", "$b/app2/secret" ]:
    ensure => directory,
    owner  => 'root',
    group  => 'root',
    mode   => 0700;
}

Dans le cas spécifique des fichiers, vous pouvez configurer une source et utiliser la récursivité:

file { "/opt/app":
  source => "puppet:///appsmodule/appsdir",
  recurse => true;
}

(cela nécessiterait d'avoir une source de cette structure de répertoire pour que la marionnette puisse l'utiliser comme source)

Vous pouvez définir un nouveau type de ressource pour réutiliser une partie du paramètre plusieurs fois:

define foo {
  file {
    "/tmp/app/${title}":
      ensure => directory,
      owner  => 'root',
      mode   => 0755;
    "/tmp/otherapp/${title}":
      ensure => link,
      target => "/tmp/app/${title}",
      require => File["/tmp/app/${title}"]
  }
}

foo { ["app1", "app2", "app3", "app4"]: } 

À partir de Puppet 2.6, il existe un Ruby DSL disponible qui a toutes les fonctionnalités de bouclage que vous pourriez demander: http://www.puppetlabs.com/blog/Ruby-dsl/ (Je ne l'ai jamais utilisé, cependant.) Dans Puppet 3.2, ils ont introduit quelques boucles expérimentales , cependant ces fonctionnalités peuvent changer ou disparaître dans les versions ultérieures.

40
freiheit

Depuis la version 3.2, il y a lambdas

Vous devez définir parser = future dans puppet.conf .

$a = [1,2,3]
each($a) |$value| { notice $value }

Une autre option pour déclarer plusieurs types définis est create_resources . Passez-lui un hachage de hachage:

create_resources(file, {
 '/tmp/test1' => { 
      ensure => directory,
      owner  => 'root',
      group  => 'root',
      mode   => '0644',
    },  
 '/tmp/test2' => { 
      ensure => directory,
      owner  => 'www-data',
      group  => 'www-data',
      mode   => '0755',
    },  
})
25
quickshiftin

Depuis Puppet 4 (et le "futur analyseur" des dernières versions de Puppet 3), le Puppet DSL a des fonctions d'itération similaires en forme et en fonction à certaines des méthodes de Ruby tableaux et hachages:

  • chaque - évalue un bloc de code (formellement, un lambda) pour chaque élément d'un tableau ou d'un hachage
  • filtre - applique un lambda à chaque élément d'un tableau ou d'un hachage et renvoie un tableau ou un hachage de ceux pour lesquels le lambda a été évalué comme vrai
  • map - applique un lambda à chaque élément d'un tableau ou d'un hachage, et retourne un tableau des résultats
  • réduire - applique un lambda à chaque élément d'un tableau ou d'un hachage pour générer un seul résultat, qu'il renvoie

Il n'y a pas de boucle for indexée le long des lignes de C ou de Java, mais vous pouvez combiner sectionnement de tablea avec l'une des fonctions ci-dessus pour réaliser l'itération sur un sous-ensemble d'une structure de données. Il n'y a pas d'itération indéfinie dans le sens d'une boucle C ou Java while.

Bien sûr, vous pouvez toujours utiliser les approches centrées sur les ressources décrites dans d'autres réponses, et parfois l'une d'entre elles est en effet la meilleure approche disponible. Vous ne pouvez plus utiliser Ruby DSL, cependant; il est complètement supprimé de Puppet 4. Parmi les fonctions d'itération, la possibilité de définir des fonctions personnalisées, l'ascension des approches centrées sur les données en faveur, et toutes les fonctionnalités standard historiques de Puppet, Ruby DSL ne semble pas beaucoup manquer.

4
John Bollinger

Oui. "Ruby DSL" pourrait vous aider, utilisez simplement l'extension de fichier ".rb" au lieu de ".pp" dans le manifeste et vous pouvez définir le "type" de marionnette comme ceci:

define 'myapps::structure', :applist do
   @applist.each do |app|
       file( @name+'/'+app, 
             :ensure => directory,
             :owner  => 'root',
             :group  => 'root',
             :mode   => '0644')
   end
end

Les classes et les nœuds peuvent également être définis de manière similaire. Notez cependant que cette fonctionnalité est déconseillée depuis la version 3

2
Aleksandr K.