Подтвердить что ты не робот

Есть ли итераторы и петли в марионетке?

Когда я определяю (?) ресурс, например. для обеспечения структуры dir, существуют ли какие-либо петли?

Вроде:

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

У меня есть десятки каталогов, и я действительно устал с объявлением его в марионетке. Это займет 15 LOC bash.

Любые идеи?

4b9b3361

Ответ 1

В марионеточном языке нет никаких циклов.

Но вы можете использовать массив вместо простой строки для заголовка и одновременно объявлять несколько ресурсов с теми же параметрами:

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

Вы также можете объявлять множество ресурсов одного и того же типа с разными параметрами, заканчивая каждый ресурс с помощью ;, который немного компактнее, чем повторение file и { и } 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;
}

В конкретном случае файлов вы можете настроить источник и использовать рекурсию:

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

(для этого требуется наличие источника этой структуры каталогов для марионетки в качестве источника)

Вы можете определить новый тип ресурса, чтобы повторно использовать часть параметра несколько раз:

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

Начиная с Puppet 2.6, имеется доступная Ruby DSL, которая имеет все возможности циклирования, которые вы могли бы запросить: http://www.puppetlabs.com/blog/ruby-dsl/ (я однако не использовал его). В Puppet 3.2 они ввели несколько экспериментальных циклов однако эти функции могут измениться или исчезнуть в последующих выпусках.

Ответ 2

Начиная с версии 3.2, lambdas

Вы должны установить parser = future в puppet.conf.

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

Другим вариантом для объявления нескольких определенных типов является create_resources. Передайте хэш хэшей:

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

Ответ 3

Как и в Puppet 4 (и "будущий парсер" поздних версий Puppet 3), кукольный DSL имеет итерационные функции, похожие по форме и функции, на некоторые из методов массивов Ruby и хэшей:

  • each - оценивает блок кода (формально, лямбда) для каждого элемента массива или хэша
  • filter - применяет лямбда к каждому элементу массива или хешу и возвращает массив или хэш из тех, для которых вычисляется лямбда к true
  • map - применяет лямбда к каждому элементу массива или хешу и возвращает массив результатов
  • reduce - применяет лямбда к каждому элементу массива или хешу, чтобы создать один результат, который он возвращает

Нет индексированного цикла for вдоль линий C или Java, но вы можете объединить секцию массива с любой из вышеперечисленных функций для достижения итерации над подмножеством структуры данных. Не существует неопределенной итерации по линиям цикла C или Java while.

Конечно, вы все равно можете использовать ориентированные на ресурсы подходы, описанные в других ответах, и иногда один из них действительно лучший доступный подход. Однако вы больше не можете использовать Ruby DSL; он полностью удаляется из Кукольного 4. Среди итерационных функций способность определять пользовательские функции, вознесение ориентированных на данные подходов в пользу и все исторические стандартные функции Puppet, Ruby DSL, кажется, не так сильно пропущены.

Ответ 4

Да. "Ruby DSL" может помочь, просто используйте расширение файла ".rb" вместо ".pp" в манифесте, и вы можете определить кукольный "тип" следующим образом:

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

Классы и узлы также могут быть определены аналогичным образом. Обратите внимание, что эта функция устарела со времени выпуска 3