puppet 无法找到依赖项

puppet 无法找到依赖项

我继承了一个 Puppet 服务器。它管理着几十台主机,大部分运行良好。

当我说大多数时候,有几位房东在办理入住手续时失败了:

Error: Failed to apply catalog: Could not find dependency File[/etc/postfix/main.cf] for Augeas[set postfix 'relayhost' to 'smtp.mydomain.net']

我仔细研究了一下,确定有问题的类定义位于文件“default.pp”中

postfix::config {
    "relayhost": value  => "smtp.mydomain.net"
}

现在,我的理解(可能不正确)是,这个文件被每个由 puppet 管理的主机使用,但问题只存在于少数主机上。大多数主机运行正常。

因此,我正在研究问题出在客户端而不是服务器的理论。

显然,首先要检查的是文件 /etc/postfix/main.cf 是否确实存在于问题主机上。答案是肯定的。

我花了一整天时间在 Google 上搜索这个问题,我发现的所有问题往往都是人们在编写清单时犯了错误。我从未发现任何人在使用清单时遇到问题,而清单在其他主机上似乎运行正常。

我是 puppet 的新手(但不是 Linux),发现它很有趣,即使从 puppet 中得到的错误消息可能有些神秘。

欢迎任何帮助。

系统是 CentOS 6,带有 puppet 3.2.3-1

- - 更新 - -

(抱歉回复晚了,因为我在澳大利亚所以时区不同)

好的,根据 Craig 在下面给出的回答,我已经在 puppetmaster 上的 puppet 目录中查找了 main.cf 的实例

root@svd7puppetmaster:/etc/puppet ] # grep -R main.cf *
modules/postfix/manifests/init.pp:  file { '/etc/postfix/main.cf':
modules/postfix/manifests/init.pp:    source  => 'puppet:///modules/postfix/main.cf',
modules/postfix/manifests/config.pp:#configuation file (/etc/postfix/main.cf).
modules/postfix/manifests/config.pp:    incl    => '/etc/postfix/main.cf',
modules/postfix/manifests/config.pp:    require => File['/etc/postfix/main.cf'],

文件内容如下(为了简洁,我删除了标题注释);

root@svd7puppetmaster:/etc/puppet ] # cat modules/postfix/manifests/init.pp

class postfix {

# selinux labels differ from one distribution to another
case $::operatingsystem {

  RedHat, CentOS: {
    case $::lsbmajdistrelease {
      '4':     { $postfix_seltype = 'etc_t' }
      '5','6': { $postfix_seltype = 'postfix_etc_t' }
      default: { $postfix_seltype = undef }
    }
  }

  default: {
    $postfix_seltype = undef
  }
}

# Default value for various options
if $postfix_smtp_listen == '' {
  $postfix_smtp_listen = '127.0.0.1'
}
if $root_mail_recipient == '' {
  $root_mail_recipient = 'nobody'
}
if $postfix_use_amavisd == '' {
  $postfix_use_amavisd = 'no'
}
if $postfix_use_dovecot_lda == '' {
  $postfix_use_dovecot_lda = 'no'
}
if $postfix_use_schleuder == '' {
  $postfix_use_schleuder = 'no'
}
if $postfix_use_sympa == '' {
  $postfix_use_sympa = 'no'
}
if $postfix_mail_user == '' {
  $postfix_mail_user = 'vmail'
}

case $::operatingsystem {
  /RedHat|CentOS|Fedora/: {
    $mailx_package = 'mailx'
  }

/Debian|kFreeBSD/: {
    $mailx_package = $::lsbdistcodename ? {
      /lenny|etch|sarge/ => 'mailx',
      default            => 'bsd-mailx',
    }
  }

  'Ubuntu': {
   if (versioncmp('10', $::lsbmajdistrelease) > 0) {
      $mailx_package = 'mailx'
    } else {
      $mailx_package = 'bsd-mailx'
    }
  }
}

$master_os_template = $::operatingsystem ? {
  /RedHat|CentOS/          => template('postfix/master.cf.redhat.erb', 'postfix/master.cf.common.erb'),
  /Debian|Ubuntu|kFreeBSD/ => template('postfix/master.cf.debian.erb', 'postfix/master.cf.common.erb'),
}

package { 'postfix':
  ensure => installed,
}

package { 'mailx':
  ensure => installed,
  name   => $mailx_package,
}

service { 'postfix':
  ensure    => running,
  enable    => true,
  hasstatus => true,
  restart   => '/etc/init.d/postfix reload',
  require   => Package['postfix'],
}

file { '/etc/mailname':
  ensure  => present,
  content => "$::fqdn\n",
  seltype => $postfix_seltype,
}

# Aliases
file { '/etc/aliases':
  ensure  => present,
  content => '# file managed by puppet\n',
  replace => false,
  seltype => $postfix_seltype,
  notify  => Exec['newaliases'],
}

# Aliases
exec { 'newaliases':
  command     => '/usr/bin/newaliases',
  refreshonly => true,
  require     => Package['postfix'],
  subscribe   => File['/etc/aliases'],
}

# Config files
file { '/etc/postfix/master.cf':
  ensure  => present,
  owner   => 'root',
  group   => 'root',
  mode    => '0644',
  content => $master_os_template,
  seltype => $postfix_seltype,
  notify  => Service['postfix'],
  require => Package['postfix'],
}

# Config files
file { '/etc/postfix/main.cf':
  ensure  => present,
  owner   => 'root',
  group   => 'root',
  mode    => '0644',
  source  => 'puppet:///modules/postfix/main.cf',
  replace => false,
  seltype => $postfix_seltype,
  notify  => Service['postfix'],
  require => Package['postfix'],
}

# Default configuration parameters
$myorigin = $valid_fqdn ? {
  ''      => $::fqdn,
  default => $valid_fqdn,
}
postfix::config {
  'myorigin':         value => $myorigin;
  'alias_maps':       value => 'hash:/etc/aliases';
  'inet_interfaces':  value => 'all';
}

case $::operatingsystem {
  RedHat, CentOS: {
    postfix::config {
      'sendmail_path':    value => '/usr/sbin/sendmail.postfix';
      'newaliases_path':  value => '/usr/bin/newaliases.postfix';
      'mailq_path':       value => '/usr/bin/mailq.postfix';
    }
  }
  default: {}
}

mailalias {'root':
  recipient => $root_mail_recipient,
  notify    => Exec['newaliases'],
   }
}

root@svd7puppetmaster:/etc/puppet ] # cat modules/postfix/manifests/config.pp

define postfix::config ($value, $ensure = present) {

    Augeas {
      incl    => '/etc/postfix/main.cf',
      lens    => 'Postfix_Main.lns',
      notify  => Service['postfix'],
      require => File['/etc/postfix/main.cf'],
    }

    case $ensure {
       present: {
         augeas { "set postfix '${name}' to '${value}'":
         changes => "set $name '$value'",
        }
    }
    absent: {
        augeas { "rm postfix '${name}'":
        changes => "rm $name",
      }
    }
    default: {}
  }
}

主机的清单非常简单。为了简洁起见,除非有人要求,否则我不会在这里发布它们。它们几乎只定义网络 IP 和 ntp 服务器。与 postfix 完全无关。它们继承自另一个清单,该清单仅涉及一些 snmp 设置和系统日志记录内容,而后者又继承自 default.pp,其中包含导致问题的 postfix 部分(在本问题的开头显示)(如果我将其注释掉,问题就会消失)

工作主机和非工作主机之间的唯一区别实际上是节点名称及其 IP 地址,否则两个清单是相同的。

如果有人想看这些文件的内容,我可以发布它们的内容。

我还检查了 postfix 模块的可用性:

root@svd7puppetmaster:/etc/puppet ] # puppet module list | grep postfix
├── postfix (???)

我假设由于模块没有以“puppetlabs”为前缀,所以它不是官方模块?我不确定还有什么其他方法可以检查这一点。

- - 更新 - -

很抱歉耽误了这么久,我们的生产系统出现了一些问题,需要一些时间才能解决,所以这件事不得不暂时搁置。

不管怎样,这让我很头疼。我已经使用了两个主机,一个可以正常工作,另一个则出现故障。

我为他们俩创建了完全空的清单:

node myhost1 {

}

应用程序清单如下:

node application {

}

然而,当我在它们上运行 Puppet 代理时,我得到了不同的结果:

[09:32:55 root@myhost01:~ ] # puppet agent --test
Info: Retrieving plugin
Info: Loading facts in /var/lib/puppet/lib/facter/os_maj_version.rb
Info: Loading facts in /var/lib/puppet/lib/facter/iptables_persistent_version.rb
Info: Loading facts in /var/lib/puppet/lib/facter/ip6tables_version.rb
Info: Loading facts in /var/lib/puppet/lib/facter/root_home.rb
Info: Loading facts in /var/lib/puppet/lib/facter/puppet_vardir.rb
Info: Loading facts in /var/lib/puppet/lib/facter/concat_basedir.rb
Info: Loading facts in /var/lib/puppet/lib/facter/pe_version.rb
Info: Loading facts in /var/lib/puppet/lib/facter/iptables_version.rb
Info: Caching catalog for myhost01.mydomain.net
Info: Applying configuration version '1426804333'
Notice: Finished catalog run in 1.00 seconds

[root@myhost02 datawarehouse]# puppet agent --test
Info: Retrieving plugin
Info: Loading facts in /var/lib/puppet/lib/facter/os_maj_version.rb
Info: Loading facts in /var/lib/puppet/lib/facter/root_home.rb
Info: Loading facts in /var/lib/puppet/lib/facter/iptables_version.rb
Info: Loading facts in /var/lib/puppet/lib/facter/concat_basedir.rb
Info: Loading facts in /var/lib/puppet/lib/facter/ip6tables_version.rb
Info: Loading facts in /var/lib/puppet/lib/facter/puppet_vardir.rb
Info: Loading facts in /var/lib/puppet/lib/facter/pe_version.rb
Info: Loading facts in /var/lib/puppet/lib/facter/iptables_persistent_version.rb
Info: Caching catalog for myhost02.mydomain.net
Error: Failed to apply catalog: Could not find dependency File[/etc/postfix/main.cf] for Augeas[set postfix 'relayhost' to 'smtp.mydomain.net']

显然,我对 Puppet 工作原理的理解严重不足,因为我无法理解为什么两个具有空清单的主机会表现不同。

无论如何,感谢你们对此事的帮助,但我认为现在我只能把它放到太难的篮子里。

答案1

这肯定是 puppetmaster 的清单出了问题,但据推测触发由于客户端的一些变化,导致在后缀模块的某处对傀儡清单的不同部分进行评估。

在 postfix 模块中的某个地方会有一个 augeas 资源,它依赖于 File['/etc/postfix/main.cf'](需要、通知、订阅等),但由于某种原因,文件 { '/etc/postfix/main.cf': } 资源尚未声明(可能在“if”或其他内容中)。但是,如果没有关于 postfix 模块的更多详细信息,很难猜测是什么。

postfix 模块是来自 puppetlabs 还是 puppetforge?如果是,是哪一个(有很多),哪个版本?如果不是,您能分享一下模块吗?

答案2

您的Error: Failed to apply catalog: Could not find dependency File[/etc/postfix/main.cf] for Augeas[set postfix 'relayhost' to 'smtp.mydomain.net']意思是您的清单中的某处有一个augeas { "set postfix 'relayhost' to ...."带有 的文件require File['/etc/postfix/main.cf'],暗示 puppet 应该首先安装 postfix 主配置,然后设置您的中继主机,而有问题的文件不是您正在应用的目录的一部分。

关于该主题的附注:如果您每次都安装 postfix 主模板,那么让 augeas edit replyhosts:puppet 会在每次运行时编辑 postfix 配置两次。您可能想要研究一下如何使用单个模板,或者在安装 postfix 主配置replace => no中添加file{}

回到你的问题,听起来你好像包括了postfix::config,但还没有包括postfix它自己,它(AFAIU)会安装 postfix 主配置。

在破坏由该 puppetmaster 驱动的每个 postfix 配置之前,您可能需要确保您在单独的环境中工作。然后,作为一个大胆的猜测/没有从您的设置中看到太多:编辑您的postfix/manifests/config.pp添加在postfix::config定义中的某处:

if (! defined(Class["postfix"])) {
    include postfix
}

请注意,它“工作”的节点现在可能会受到重复后缀定义的影响:寻找添加该定义检查的其他包含内容,...

作为免责声明:除非您知道自己在做什么,否则不应编辑 Puppet 清单(考虑到所有注册的客户端都会刷新其配置,...即使在最佳条件下,任何事情都可能中断,...)

相关内容