简体   繁体   English

人偶在多个模块中调用相同的服务?

[英]Puppet calls same service in multiple module?

I have a puppet module A. In that module I have a service restart for a change in file. 我有一个人偶模块A。在该模块中,我重新启动了服务以更改文件。

class A::test1 { 
  include ::corednsclient
  service { 'sshd':
    ensure => running,
    enable => true,
  }
}

Now , I have a different puppet module B. In that module also I have to restart the same service for a change in another file. 现在,我有一个不同的人偶模块B。在该模块中,我还必须重新启动相同的服务才能更改另一个文件。

Now , the problem is that I'm getting the following: 现在,问题是我得到以下信息:

Duplicate declaration error

when I'm doing /opt/puppetlabs/bin/puppet apply --modulepath=/abc xyz/site.pp 当我在做/ opt / puppetlabs / bin / puppet时--modulepath = / abc xyz / site.pp

If I runs each module independently as puppet apply -e 'include moduleA' and puppet apply -e 'include moduleB' , Both would works fine. 如果我像puppet apply -e'include moduleA'puppet apply -e'include moduleB'一样独立运行每个模块,两者都可以正常工作。 But puppet apply globally seems to be failing. 但是p在全球范围内适用似乎失败了。

Any help would be highly appreciated ! 任何帮助将不胜感激!

Error: Evaluation Error: Error while evaluating a Resource Statement,
 Duplicate declaration: Service[sshd] is already declared in file 
 /export/content/ucm/puppet/modules/coresshd/manifests/configure.pp:28; cannot
 redeclare at 
 /export/content/ucm/puppet/modules/corednsclient/manifests/daemon_reload.pp:10 at 
 /export/content/ucm/puppet/modules/corednsclient/manifests/daemon_reload.pp:10:3 on 
 node lor1-0002276.int.xxx.com .

Yes, this is normal. 是的,这很正常。 Puppet only allows resources to be declared once. 木偶只允许声明一次资源。 In general, if you have code like: 通常,如果您有如下代码:

class aaa {
  notify { 'xxx': message => 'yyy' }
}

class bbb {
  notify { 'xxx': message => 'yyy' }
}

include aaa
include bbb

Puppet apply that and you will see an error like this: 木偶将其应用,您将看到如下错误:

Error: Evaluation Error: Error while evaluating a Resource Statement,
 Duplicate declaration: Notify[xxx] is already declared at (file: ...test.pp, 
 line: 2); cannot redeclare (file: ...test.pp, line: 6) (file: ...test.pp, line: 6,
 column: 3) on node ...

Workarounds 解决方法

Solution 1 Refactor so both classes inherit a third class 解决方案1重构,以便两个类都继承第三个类

Generally, the best way to resolve this is to refactor your code so that there is a third class that contains the duplicated resource, and other classes include that using the include function, like this: 一般情况下,要解决它的最好方法就是重构你的代码,以便有一个包含重复的资源三等功,以及其他类包括使用include函数,就像这样:

class ccc {
  notify { 'xxx': message => 'yyy' }
}

class aaa {
  include ccc
}

class bbb {
  include ccc
}

include aaa
include bbb

That works fine. 很好

Note that this only works because the include function can be called any number of times, unlike a resource declaration - also unlike the resource-like class declarations. 请注意,这仅行得通,是因为include函数可以多次调用,这与资源声明不同-与资源类声明不同。

You can read more about "include-like v resource-like class declarations" here . 您可以在此处阅读更多有关“类包含v类资源的声明”的内容。

Solution 2 Use virtual resources 解决方案2使用虚拟资源

You can also use virtual resources . 您还可以使用虚拟资源 Refactor like this: 像这样重构:

class ccc {
  @notify { 'xxx': message => 'yyy' }
}

class aaa {
  include ccc
  realize Notify['xxx']
}

class bbb {
  include ccc
  realize Notify['xxx']
}

include aaa
include bbb

An added advantage of this one is you can use resource collectors and select only specific resources from a set of virtual resources, like this: 此功能的另一个优点是,您可以使用资源收集器,并从一组虚拟资源中仅选择特定资源,如下所示:

class ccc {
  @notify { 'ppp': message => 'xxx' }
  @notify { 'qqq': message => 'yyy' }
  @notify { 'rrr': message => 'zzz' }
}

class aaa {
  include ccc
  Notify <| message == 'xxx' |>
}

class bbb {
  include ccc
  Notify <| message == 'xxx' or message == 'yyy' |>
}

include aaa
include bbb

If you don't need this functionality here, as appears the case, you probably should use the first proposal. 如果您在这里不需要此功能(如实际情况),则可能应该使用第一个建议。

Solution 3 Use ensure resource 解决方案3使用确保资源

Another option is the ensure_resources function in stdlib: 另一种选择是stdlib中的ensure_resources函数:

class aaa {
  ensure_resources('notify', {'xxx' => {'message' => 'yyy'}})
}

class bbb {
  ensure_resources('notify', {'xxx' => {'message' => 'yyy'}})
}

include aaa
include bbb

Solution 4 Use defined 解决方案4使用定义

Historically this is strongly advised against, although the docs do not mention any reason to not use it. 从历史上看,强烈建议不要这样做,尽管文档中没有提及任何不使用它的理由。 It is possible to use the defined like this: 可以这样使用defined

class aaa {
  if ! defined(Notify['xxx']) {
    notify { 'xxx': message => 'yyy' }
  }
}

class bbb {
  if ! defined(Notify['xxx']) {
    notify { 'xxx': message => 'yyy' }
  }
}

include aaa
include bbb

This way, the resource is added to the catalog only if it is not already in there. 这样,仅当资源不在目录中时,才将其添加到目录中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM