37

当我定义(?)一个资源时,例如确保目录结构,是否有可用的循环?

像那样:

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

我有几十个目录,我真的很厌倦在 puppet 中声明它。这需要 15 LOC 的 bash。

有任何想法吗?

4

4 回答 4

41

旧版本的木偶语言不支持循环。

但是您可以使用数组而不是简单的字符串作为标题,并使用相同的参数同时声明多个资源:

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

您还可以通过以 a 结束每个资源来声明许多具有不同参数的相同类型的资源;,这比重复s 和files更紧凑:{}

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;
}

(这将需要该目录结构的源以供 puppet 用作源)

您可以定义一个新的资源类型以多次重用参数的一部分:

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 中,他们引入了一些实验性循环,但是这些功能可能会在以后的版本中改变或消失。

于 2011-06-19T15:55:03.117 回答
27

从 3.2 版开始,有lambdas

您必须parser = futurepuppet.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',
    },  
})
于 2013-10-31T05:07:18.110 回答
4

从 Puppet 4(以及 Puppet 3 后期版本的“未来解析器”)开始,Puppet DSL 的迭代函数在形式和功能上与 Ruby 数组和哈希的一些方法相似:

  • each - 为数组或散列的每个元素计算一个代码块(正式地,一个 lambda)
  • filter - 将 lambda 应用于数组或散列的每个元素,并返回 lambda 评估为 true 的数组或散列
  • map - 将 lambda 应用于数组或哈希的每个元素,并返回结果数组
  • reduce - 将 lambda 应用于数组或哈希的每个元素以构建单个结果,然后返回

没有for像 C 或 Java 那样的索引循环,但是您可以将数组分段与上述任何函数结合起来,以实现对数据结构子集的迭代。whileC 或 Java循环中不存在无限迭代。

当然,您仍然可以使用其他答案中描述的以资源为中心的方法,有时其中之一确实是最好的可用方法。但是,您不能再使用 Ruby DSL。它从 Puppet 4 中完全删除。在迭代函数、定义自定义函数的能力、以数据为中心的方法的提升以及所有 Puppet 的历史标准特性中,Ruby DSL 似乎并没有太多错过。

于 2015-12-08T18:55:28.033 回答
2

是的。“Ruby DSL”可能会有所帮助,只需在清单中使用文件扩展名“.rb”而不是“.pp”,您可以像这样定义 puppet “type”:

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

类和节点也可以用类似的方式定义。但请注意,此功能自第 3 版起已弃用

于 2013-07-03T12:29:39.627 回答