15

Puppetlabs のドキュメントには、あるクラスが別のクラスを必要とするようにするには、リレーションシップ チェーン構文を使用し、外部ノードで両方のクラスを宣言する必要があると記載されています。

各モジュールの多くのパッケージが依存する yum リポジトリ定義を作成するリポジトリ クラスがあります。各モジュールには Class['repo'] -> Class['modulename'] ステートメントがあり、両方のクラスがノードで宣言されています。ただし、パペットが実行されると、モジュール クラスの前にリポジトリ クラスが期待どおりに実行されるとは限りません。なぜだめですか?以下の例 (パペット 2.6.16):

編集:この問題には 3 つの基本的な解決策があるようです。

  1. before/require メタパラメータを使用して、クラスの依存関係をリソースの依存関係に置き換えます (turingmachine の回答に示されているように)。
  2. 外部クラスの依存関係を削除し、内部クラス間の依存関係を明示的に述べます。
  3. stdlib モジュールで Puppetlabs が提供するアンカー タイプを使用して、依存するクラスがチェーン構文を使用して外部クラスへの参照を作成できるようにするクラスを含めます。

Puppet v3 と、今後もリファクタリングを最小限に抑えたいという要望を考慮して、これらのアプローチのどれが最適ですか?」

マニフェストpuppettest.pp:

class { 'repo': }
class { 'maradns': }

class repo {
  class { 'repo::custom': }
}

class repo::custom {
  yumrepo {'custom':
    enabled  => 1,
    gpgcheck => 0,
    descr    => "Local respository - ${::architecture}",
    baseurl  => 'http://repo.nike.local/CentOS/\$releasever/\$basearch';
  }
}

class maradns {
  Class['repo'] -> Class['maradns::install']
  Class['maradns::install'] -> Class['maradns::config']
  Class['maradns::config'] ~> Class['maradns::service']
  class { 'maradns::install': }
  class { 'maradns::config':  }
  class { 'maradns::service': }
}

class maradns::install {
  package { 'maradns':
    ensure  => present,
  }
}

class maradns::config {
  file { 'mararc':
    ensure  => present,
    path    => '/etc/mararc',
    mode    => '0644',
    owner   => root,
    group   => root,
  }
}

class maradns::service {
  service { 'maradns':
    ensure     => running,
    enable     => true,
    hasrestart => true,
  }
}

出力:

puppet apply puppettest.pp    
err: /Stage[main]/Maradns::Install/Package[maradns]/ensure: change from absent to present failed: Execution of '/usr/bin/yum -d 0 -e 0 -y install maradns' returned 1: Error: Nothing to do

notice: /Stage[main]/Maradns::Config/File[mararc]: Dependency Package[maradns] has failures: true
warning: /Stage[main]/Maradns::Config/File[mararc]: Skipping because of failed dependencies
notice: /Stage[main]/Maradns::Service/Service[maradns]: Dependency Package[maradns] has failures: true
warning: /Stage[main]/Maradns::Service/Service[maradns]: Skipping because of failed dependencies
notice: /Stage[main]/Repo::Custom/Yumrepo[custom]/descr: descr changed '' to 'Local respository - x86_64'
notice: /Stage[main]/Repo::Custom/Yumrepo[custom]/baseurl: baseurl changed '' to 'http://repo.test.com/CentOS/\$releasever/\$basearch'
notice: /Stage[main]/Repo::Custom/Yumrepo[custom]/enabled: enabled changed '' to '1'
notice: /Stage[main]/Repo::Custom/Yumrepo[custom]/gpgcheck: gpgcheck changed '' to '0'
notice: Finished catalog run in 2.15 seconds
4

4 に答える 4

6

依存関係の問題をデバッグするための適切な出発点は、依存関係グラフを生成するようにパペットに指示することです。

puppet apply --graph --noop manifest.pp
dot -Tpng /var/lib/puppet/state/graphs/relationships.dot -o relationships.png

これを行うと、クラスrepo:customに依存情報がまったくないことがわかります。

maradns::installは確かにクラスに依存していますが、repoクラスrepo::customrepo::customは依存していませんrepo

新しいクラス宣言構文class {'classname':}は依存関係を設定せず、include classname構文と同じように動作します。

したがって、からrepo::customへの依存関係を設定するか、クラスに直接依存するようにクラスにrepo指示します。maradns::installrepo:custom

しかし、あなたはより多くの問題に遭遇するでしょう。クラスへの依存関係は、このクラスが適用されることを確認するだけです。ただし、リソースを含むことに依存関係は設定されません。

私はあなたのケースを次のようにモデル化します:

class { 'repo:custom': }
class { 'maradns': }

class repo {
}

class repo::custom {
  yumrepo {'custom':
    enabled  => 1,
    gpgcheck => 0,
    descr    => "Local respository - ${::architecture}",
    baseurl  => 'http://repo.nike.local/CentOS/\$releasever/\$basearch';
  }
}

class maradns {
  class{[
    'maradns::package',
    'maradns::config',
    'maradns::service',
  ]:}
}

class maradns::package {
  package { 'maradns':
    ensure  => present,
    require => Yumrepo['custom'],
  }
}

class maradns::config {
  file { 'marac:config':
    ensure  => present,
    mode    => '0644',
    owner   => root,
    group   => root,
  }
}

class maradns::service {
  service { 'maradns':
    ensure     => running,
    enable     => true,
    hasrestart => true,
    require => [
      Package['maradns'],
      File['mararc:config'],
    ],
  }
}
于 2012-07-25T16:49:15.090 に答える
4

代替メカニズムとしてステージの実行を検討しましたか? 実行ステージでは、クラスを「ステージ」に関連付けることができます。デフォルトでは、すべてがメインステージで発生します。ただし、メインの前に発生するステージを設定し、そのクラスをその「メインの前」ステージに関連付けることができます。

レポは、ステージ前の非常に良い候補です。リポジトリが希望どおりに設定される前に、パッケージが取得されることは本当に望ましくありません。独自のパッケージ リポジトリをミラーリングしていて、公式リポジトリに遅れをとっている場合は、大きな頭痛の種になる可能性があります。

より厄介なシナリオは、新しい人形化されたサーバーが、リポジトリを宣言する前に誤ってパッケージをフェッチし、最新の公開ミラーからパッケージを取得する場合です。次にレポがインストールされます (おそらく、公開ミラーを削除したと思われます)。このマシンは新しいアーティファクトに「忍び込む」ため、依存関係の地獄の状況が簡単に発生し、あまりにも新しいパッケージが気になるパッケージのインストールを妨げます。 -新しいバージョンと多くのパッケージ マネージャーはダウングレードしません。手動で介入する必要があります。この状況を修正するには、基本的に手動でデバッグする必要があります。人形のルールを修正するだけでは十分ではありません。

したがって、すべてのレポ定義を before フェーズに関連付けるだけで完了です。パッケージの依存関係を追跡するのをやめて、レポジトリと呼吸を楽にします。

于 2012-08-03T03:02:51.870 に答える
4

puppetlabs stdlib ドキュメントから

Puppet 2.6 では、クラスが別のクラスを宣言すると、内部クラスのリソースは外部クラスに含まれません。これは、エンドユーザーが外部クラスと他のモジュールとの間の順序関係を指定することを不可能にするため、小さなクラスから複雑なモジュールを構成するパターンとうまく相互作用しません。

アンカー タイプを使用すると、これを回避できます。外部クラスに含まれる2 つの no-op リソースの間に内部クラスを挟むことで、モジュール内のすべてのリソースが確実に含まれるようにすることができます。

投稿されたマニフェストに基づくと、例は次のようになります。

マニフェストpuppettest.pp:

class { 'repo': }
class { 'maradns': }

class repo {
  anchor { 'repo::begin': } ->
  class { 'repo::custom': } ->
  anchor { 'repo::end': }
}

class repo::custom {
  yumrepo {'custom':
    enabled  => 1,
    gpgcheck => 0,
    descr    => "Local respository - ${::architecture}",
    baseurl  => 'http://repo.nike.local/CentOS/\$releasever/\$basearch';
  }
}

class maradns {
  Class['repo'] -> Class['maradns::install']
  Class['maradns::install'] -> Class['maradns::config']
  Class['maradns::config'] ~> Class['maradns::service']
  class { 'maradns::install': }
  class { 'maradns::config':  }
  class { 'maradns::service': }
}

class maradns::install {
  package { 'maradns':
    ensure  => present,
  }
}

class maradns::config {
  file { 'mararc':
    ensure  => present,
    path    => '/etc/mararc',
    mode    => '0644',
    owner   => root,
    group   => root,
  }
}

class maradns::service {
  service { 'maradns':
    ensure     => running,
    enable     => true,
    hasrestart => true,
  }
}
于 2012-07-26T14:25:00.237 に答える