Puppet 条件语句的伪重复声明错误

Puppet 条件语句的伪重复声明错误,puppet,puppet-enterprise,Puppet,Puppet Enterprise,我正在尝试为Puppet postgresql资源配置全局设置。我想有条件地做这件事。我使用if语句根据变量的内容对其进行配置 define setup_postgresql_globals ( $datadir, ) { if $datadir { class { 'postgresql::globals': datadir => "${datadir}", needs_initdb => true, ver

我正在尝试为Puppet postgresql资源配置全局设置。我想有条件地做这件事。我使用
if
语句根据变量的内容对其进行配置

define setup_postgresql_globals (
  $datadir,
) {
  if $datadir {
    class { 'postgresql::globals':
      datadir         => "${datadir}",
      needs_initdb    => true,
      version         => '9.3',
    }
  }
  else {
    class { 'postgresql::globals':
      needs_initdb    => true,
      version         => '9.3',
    }
  }
}
我得到了这个错误

Error: Duplicate declaration: Class[Postgresql::Globals] is already declared
我只想将
datadir
参数传递给
postgresql::globals
,如果它包含一个值

如何使用条件语句而不获得重复的声明错误

如何使用条件语句而不获得重复的声明错误

问题不在于条件语句,而在于您声明了多个
setup\u postgresql\u globals
实例。每次都声明同一个类,尽管类是幂等的并且可以多次声明,但只有给定类的声明的第一次求值才能使用。所有其他人都必须使用include-like语法的变体之一

部分原因是,将类似资源的类声明放入定义的类型中是一种糟糕的形式。这样做是自找麻烦。如果需要使用类似于类声明的资源,请将其放在另一个类中。这可能完全解决了问题,但最坏的情况是将问题推向更高的层次。在您的例子中,这似乎是一种合理的方法,因为
设置\u postgresql\u globals
确实听起来应该是幂等的

还要考虑类(而不是定义类)可以使用自动数据绑定。依靠外部数据自动绑定到类参数通常是用类似include的类声明替换类似资源的类声明的好方法。在适当的控制下应用,可以产生更干净、更简单、更易于使用和维护的清单

如何使用条件语句而不获得重复的声明错误

问题不在于条件语句,而在于您声明了多个
setup\u postgresql\u globals
实例。每次都声明同一个类,尽管类是幂等的并且可以多次声明,但只有给定类的声明的第一次求值才能使用。所有其他人都必须使用include-like语法的变体之一

部分原因是,将类似资源的类声明放入定义的类型中是一种糟糕的形式。这样做是自找麻烦。如果需要使用类似于类声明的资源,请将其放在另一个类中。这可能完全解决了问题,但最坏的情况是将问题推向更高的层次。在您的例子中,这似乎是一种合理的方法,因为
设置\u postgresql\u globals
确实听起来应该是幂等的

还要考虑类(而不是定义类)可以使用自动数据绑定。依靠外部数据自动绑定到类参数通常是用类似include的类声明替换类似资源的类声明的好方法。在适当的控制下应用,可以产生更干净、更简单、更易于使用和维护的清单

如果datadir参数包含值,我只想将其传递给postgresql::globals

如果数据目录不包含值,则不必担心无法传递数据目录。只需将参数与其他参数一起传递给
postgresql::globals
。如果
datadir
有一个值,类将使用它,如果没有,则
postgresql::globals
将处理它,并使用它自己的默认值。您需要修改传递参数的方式,但这不起作用:
datadir=>“${datadir}”
,您必须像这样传递参数。您的定义可以如此简单:

define setup_postgresql_globals (
  $datadir = undef,
) {
  class { 'postgresql::globals':
    datadir         => $datadir,
    needs_initdb    => true,
    version         => '9.3',
  }
}
获取
错误的原因:重复声明:类[Postgresql::Globals]已声明
,因为您正在实例化定义多模块时间。从本质上讲,定义可以多次实例化,因此在一个定义中执行像include这样的类可能会有问题,因为这样的类只能包含一次。有几种方法可以解决此问题

1) 评估您对该定义的需求。创建此定义只是为了处理
datadir
参数作为
unde
值。正如我所展示的那样,您可能不需要这个定义,因为不需要您的逻辑

2) 您应该只在define中执行类的基本包含。您可以安全地多次包含这样的类。您必须通过hiera的自动参数查找系统处理设置
datadir
。例如:

define setup_postgresql_globals (
  $datadir = undef,
) {
  include 'postgresql::globals'
}
同样,您可能应该从实例化
setup\u postgresql\u globals
的位置删除此定义和句柄,包括
postgresql::globals

如果datadir参数包含值,我只想将其传递给postgresql::globals

如果数据目录不包含值,则不必担心无法传递数据目录。只需将参数与其他参数一起传递给
postgresql::globals
。如果
datadir
有一个值,类将使用它,如果没有,则
postgresql::globals
将处理它,并使用它自己的默认值。您需要修改传递参数的方式,但这不起作用:
datadir=>“${datadir}”
,您必须像这样传递参数。您的定义可以如此简单:

define setup_postgresql_globals (
  $datadir = undef,
) {
  class { 'postgresql::globals':
    datadir         => $datadir,
    needs_initdb    => true,
    version         => '9.3',
  }
}
获取
错误的原因:重复声明:类[Postgresql::Globals]已声明
,因为您正在实例化定义多模块时间。本质上,定义可以多次实例化,因此像i这样的类可能会有问题