[英]How to use Puppet parameterized classes to force order of resources applied?
Puppetlabs文檔聲明,為了讓一個類需要另一個類,您應該使用關系鏈接語法並在外部節點中聲明這兩個類。
我有一個repo類,它創建了yum repo定義,每個modole中的許多包都依賴於它。 在每個模塊中,我有一個Class ['repo'] - > Class ['modulename']語句,這兩個類都在節點中聲明。 但是,當puppet運行時,它並不總是按預期在模塊類之前執行repo類。 為什么不? 以下示例(木偶2.6.16):
編輯:這個問題似乎有3個基本解決方案。
那么考慮到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
調試依賴性問題的一個很好的起點是指示puppet生成依賴圖。
puppet apply --graph --noop manifest.pp
dot -Tpng /var/lib/puppet/state/graphs/relationships.dot -o relationships.png
通過執行此操作,您將看到類repo:custom
根本沒有依賴項信息。
maradns::install
確實對repo
類有依賴,但對repo::custom
類沒有依賴,因為repo::custom
對repo
沒有依賴性。
新的類聲明語法class {'classname':}
沒有設置任何依賴項,它的行為就像include classname
語法一樣。
因此要么設置從repo::custom
到repo
的依賴關系,要么指示maradns::install
類直接依賴於repo: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'],
],
}
}
在Puppet 2.6中,當一個類聲明另一個類時,內部類中的資源不包含在外部類中。 這與從較小的類組成復雜模塊的模式非常相互作用,因為它使最終用戶無法指定外部類和其他模塊之間的順序關系。
錨類型可讓您解決此問題。 通過兩者之間夾的任何內部類是由外部類含無操作的資源,可以確保模塊中的所有資源都包含。
根據發布的清單,一個例子是:
清單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,
}
}
您是否將運行階段視為替代機制? 通過運行階段,您可以將類與“階段”相關聯。 默認情況下,一切都在主階段發生。 但是你可以設置一個在main之前發生的階段,然后將該類與'before'階段相關聯。
回購是前一階段非常好的候選人。 您真的不希望在您的存儲庫按照您想要的方式設置之前檢索任何包; 如果您正在鏡像自己的包裝回購並且滯后於官方回購,那將是一個巨大的麻煩。
更棘手的情況是,一個新的木偶化服務器在你甚至宣布你的回購之前意外地抓取了一個包,它從最新的公共鏡像中得到它; 然后你的 repo被安裝(並且可能你現在已經刪除了公共鏡像)。 因為這台機器“偷偷摸摸”了一個新的工件,所以很容易出現依賴性地獄情況,因為太新的軟件包會阻止你關心的軟件包被安裝,因為有問題的軟件包將無法安裝因為你已經安裝了 - 新版本和許多軟件包管理器不會為您降級; 你必須手動干預。 這種情況基本上需要手動調試來修復; 僅僅修復你的傀儡規則是不夠的,因為傷害已經完成。
因此,只需將所有repo定義與之前的階段相關聯,並完成它。 停止跟蹤您的包的依賴關系以便更好地恢復和呼吸。
你通過在repo中包含repo :: custom而不是直接依賴repo :: custom來獲得什么?
在類之類中聲明類的模式也可能為重復定義做好准備。 如果可能的話,我會專注於直接使用repo :: custom。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.