web-dev-qa-db-ja.com

Puppetは、モジュールが変更されるたびにエラーを生成します

私は次のように些細な人形2.7.18をインストールしています:

=== manifests/site.pp ===
node build-1 {
  include mod1
  include mod2
  include mod3
}

=== modules/mod1/manifests/init.pp ===
import "*"

=== modules/mod1/manifests/mod1.pp ===
class mod1 {
  file { "/tmp/mod1.file": ensure => present }
}

=== modules/mod2/manifests/init.pp ===
import "*"

=== modules/mod2/manifests/mod2.pp ===
class mod2 {
  file { "/tmp/mod2.file": ensure => present }
}

=== modules/mod3/manifests/init.pp ===
import "*"

=== modules/mod3/manifests/mod3.pp ===
class mod3 {
  file { "/tmp/mod3.file": ensure => present }
}

Build-1ホストでpuppetエージェントを実行しようとすると、次のメッセージが表示されます。

: 0 build-1; Sudo puppet agent --noop --test
err: Could not retrieve catalog from remote server: Error 400 on SERVER: Could not find class mod1 for build-1 at /etc/puppet/manifests/site.pp:2 on node build-1
warning: Not using cache on failed catalog
err: Could not retrieve catalog; skipping run

もう一度実行すると、同じメッセージが表示されますが、クラスmod2が対象です。 3回実行すると、クラスmod3のメッセージが表示されます。最後に、4回実行すると機能します。ただし、モジュールファイルの1つ(mod1.ppなど)に触れるだけの場合は、すべてをもう一度実行する必要があります。すべてのモジュールが正しく再コンパイルされるまで、puppetエージェントを実行します。これは明らかに持続可能ではありません。

私が気づいた他のいくつかのこと:

  1. これは https://stackoverflow.com/questions/15289988/puppet-could-not-find-class-hiccups-often-once-after-manifest-module-change に似ているようですが、バージョン3.0用のようで、それが参照するバグチケットは、2.7には影響しないと具体的に述べています。いずれにせよ、乗客のセットアップに切り替えることは役に立ちませんでした。
  2. モジュールレイアウトを変更して、実際のモジュール定義をインポートするのではなく、モジュール定義全体をinit.ppに入れるだけでも、問題は発生しません。しかし、それは複雑なモジュールに対してはうまく拡張できません。
1
Rudedog

init.ppファイルにメインクラスの定義を含めることができない理由はありますか?

クラスの発見についての私の理解は初歩的ですが、ファイルmodules/mod1/mod1.ppは、mod1::mod1クラスではなく、mod1クラスに対して自動的にチェックされます。

私の知る限り、mod1クラスは常にinit.ppで定義する必要がありますが、モジュール全体の構成がそこにある必要があるという意味ではありません。サブクラスが役立ちます。

最近推奨されていると私が信じているモジュール設計は、次のようなものです。

mod1/init.pp

class mod1 {
  include mod1::install
  include mod1::config
  include mod1::service
}

mod1/install.pp

class mod1::install {
  package { "somepackage":
    ensure => installed,
  }
}

mod1/config.pp

class mod1::config {
  file { "/etc/someapp.conf":
    content => "foo",
    require => Class["mod1::install"],
    notify  => Class["mod1::service"],
  }
}

mod1/service.pp

class mod1::service {
  service { "someapp":
    ensure => running,
  }
}

編集:さらに、モジュール内でimportを使用しないでください:

http://docs.puppetlabs.com/puppet/2.7/reference/lang_import.html

自動ロードされたマニフェスト内のインポートの動作は定義されておらず、Puppetのマイナーバージョン間でランダムに異なる場合があります。モジュールにインポートステートメントを配置しないでください。それらはsite.ppにのみ存在する必要があります。

2
Shane Madden