2011-06-19 17 views
35

Cuando defino (?) Un recurso, p. para asegurar la estructura del directorio, ¿hay algún bucle disponible?¿hay iteradores y bucles en el títere?

Al igual que:

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

tengo decenas de directorios y estoy realmente cansado con la que se declara en la marioneta .. Se necesitarían 15 LOC de fiesta.

¿Alguna idea?

Respuesta

40

En el lenguaje de títeres, no, no hay bucles.

Pero se puede utilizar una matriz en lugar de una cadena simple para el título y declarar varios recursos al mismo tiempo con los mismos parametros:

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

También puede declarar muchos recursos del mismo tipo con diferentes params por finalización de cada recurso con un ;, que es un poco más compacto que la repetición de la file y los { s y } 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; 
} 

en el caso específico de archivos, puede configurar un origen y el uso de recursividad:

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

(que requeriría que tiene una fuente de esa estructura de directorios de la marioneta que se utilizará como fuente)

Usted puede define a new resource type reutilizar una parte de los param varias veces:

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"]: } 

a partir de la marioneta 2.6, hay un DSL Rubí disponibles que tiene toda la funcionalidad de bucle que se puede pedir: http://www.puppetlabs.com/blog/ruby-dsl/ (nunca he utilizado, sin embargo). En Puppet 3.2, introdujeron algunos experimental loops, sin embargo, esas características pueden cambiar o desaparecer en versiones posteriores.

+1

Gracias! cómo hacerlo funcionar: archivo {[X, Y]: asegurar = enlace, destino => [X1 + X, Y1 + Y]}? – user425720

+1

Puede usar un definir. Agregué un ejemplo a mi respuesta – freiheit

+0

aah, perfecto. ¡Gracias! – user425720

2

Sí. "Ruby DSL" podría ayudar, sólo tiene que utilizar la extensión de archivo ".rb" en lugar de ".pp" en el manifiesto y se puede definir títere 'tipo' de esta manera:

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

Las clases y los nodos también se pueden definir en similares camino. Nótese sin embargo que esta característica es deprecated desde el lanzamiento 3

25

partir de la versión 3.2 hay lambdas

Debe establecer parser = future en puppet.conf.

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

Otra opción para la declaración de varios tipos definidos es create_resources.Pase que un hash de hashes:

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', 
    }, 
}) 
+5

La solución de cada() es la única solución real a este problema que he visto hasta ahora. – markus

+0

@markus, estoy de acuerdo, sin embargo, para ser justos, no estoy seguro de que estuviera disponible cuando esta pregunta se hizo originalmente en 2011. Sin embargo, esperamos que esto llegue a la cima de esta pregunta para que la gente no pierda el tiempo, ahora que _lambdas_ están disponibles. – quickshiftin

+4

Si está utilizando 'marioneta aplicar' asegúrese de habilitar el futuro analizador' marioneta aplicar --parser = futuro' – quickshiftin

4

A partir de la marioneta 4 (y el "analizador futuro" de las versiones finales de los años de la marioneta 3) el de marionetas DSL tiene funciones de iteración similares en forma y función a algunos de los métodos de Ruby arrays y hashes:

  • each - evalúa un bloque de código (formalmente, un lambda) para cada elemento de una matriz o de hash
  • filter - se aplica un lambda a cada elemento de una matriz o de hash y devuelve una array o hash de aquellos para los que la lambda se evaluó como verdadera
  • map - se aplica un lambda a cada elemento de una matriz o de hash, y devuelve una matriz de los resultados
  • reduce - se aplica un lambda a cada elemento de una matriz o de hash para construir un único resultado, que devuelve

no hay indexada for bucle a lo largo de las líneas C de Java o de, pero se puede combinar array sectioning con cualquiera de las funciones anteriores para conseguir iteración sobre un subconjunto de una estructura de datos. No hay iteración indefinida en las líneas de un C o Java while loop.

Por supuesto, puede seguir utilizando los enfoques centrados en los recursos que se describen en otras respuestas, y en ocasiones uno de ellos es de hecho el mejor enfoque disponible. Sin embargo, ya no puedes usar Ruby DSL; se elimina por completo de Puppet 4. Entre las funciones de iteración, la capacidad de definir funciones personalizadas, la ascensión de los enfoques centrados en datos a favor y todas las características estándar históricas de Puppet, Ruby DSL parece no perderse mucho.