web-dev-qa-db-ja.com

別々のクラスで定義された同じリソースの重複した宣言

build-essentialパッケージを必要とするクラス定義があります。

class erlang($version = '17.3') {

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

別のモジュールの別のクラスにもbuild-essentialパッケージが必要です。

class icu {

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

ただし、パペットアプライを実行しようとすると、次のエラーが表示されます。

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

クラスが使用するリソースをカプセル化することを期待していましたが、そうではないようです。この衝突を解決するにはどうすればよいですか?

10
Chris Snow

これは、複数のモジュールを扱うときによくある質問です。

これを行うにはいくつかの方法があります。ベストプラクティスは、モジュール化して、パラメーターとして不可欠なビルドのインストールを許可することです。

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')
15
Peter Souter

両方のモジュールを制御する場合は、共有リソースを管理するための3番目のクラス(モジュール)を作成する必要があります。

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

パッケージだけを必要とするコンテキスト

include build_essential

12 "のポールでdefined()関数に触れないでください。この道では痛みしかありません。

5
Felix Frank

他の回答で説明されているように複数の方法がありますが、同じリソースを複数回使用する場合、これは別の信頼できる方法です。

一度宣言してから、それを複数回実現します。たとえば、次のような新しい仮想リソースを作成します。

モジュール/パッケージ/マニフェスト/init.pp内

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

次に、両方のクラスに、上記の仮想リソースを実現するために以下の行を含めます

include packages
realize Package('build-essential')
1
Jayabalan Bala