在单独的类中定义的相同资源的重复声明

时间:2014-10-05 18:14:04

标签: puppet

我有一个类定义,需要build-essential包:

class erlang($version = '17.3') {

  package { "build-essential": 
    ensure => installed
  }
  ...
}

另一个模块中的另一个类也需要build-essential包:

class icu {

  package { "build-essential": 
    ensure => installed
  }
  ...
}

但是,当我尝试执行puppet apply时,我收到的错误是:

Error: Duplicate declaration: Package[build-essential] is already declared in file /vagrant/modules/erlang/manifests/init.pp:18; cannot redeclare at /vagrant/modules/libicu/manifests/init.pp:17 on node vagrant-ubuntu-trusty-64.home

我期望类封装他们使用的资源,但似乎并非如此?我该如何解决这个冲突?

3 个答案:

答案 0 :(得分:14)

这是处理多个模块时的常见问题。

有很多方法可以做到这一点,最佳做法是模块化并允许安装必要的构建作为参数:

class icu ($manage_buildessential = false){

  if ($manage_buildessential == true) {
   package { "build-essential": 
     ensure => installed
   }
 }
}

然后,您想要包含您的ICU类:

class {'icu':
   manage_buildessential => 'false',
}

然而,快速而肮脏的修复:

if ! defined(Package['build-essential']) {
    package { 'build-essential': ensure => installed }
}

或者如果你有puppetlabs-stdlib模块:

ensure_packages('build-essential')

答案 1 :(得分:5)

如果您控制两个模块,则应编写第三个类(模块)来管理共享资源。

class build_essential {
    package { 'build-essential': ensure => installed }
}

需要包的上下文

include build_essential

不要用12“极点触摸已定义的()函数。这条路上只会有痛苦。

答案 2 :(得分:0)

其他答案解释了多种方式,但是如果您想多次使用同一资源,这是另一种可靠的方式。

声明一次,然后多次实现。例如,创建一个新的虚拟资源,如下所示:

在模块/软件包/清单/init.pp中

class packages {
  @package{ 'build-essential':
    ensure => installed
  }
}

然后,在您的两个课程中,都包含以下几行以实现上述虚拟资源

include packages
realize Package('build-essential')