如何使用Puppet参数化类来强制应用资源的顺序?

Mic*_*lle 15 puppet

Puppetlabs文档声明,为了让一个类需要另一个类,您应该使用关系链接语法并在外部节点中声明这两个类.

我有一个repo类,它创建了yum repo定义,每个modole中的许多包都依赖于它.在每个模块中,我有一个Class ['repo'] - > Class ['modulename']语句,这两个类都在节点中声明.但是,当puppet运行时,它并不总是按预期在模块类之前执行repo类.为什么不?以下示例(木偶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,
  }
}
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

tur*_*ine 6

调试依赖性问题的一个很好的起点是指示puppet生成依赖图.

puppet apply --graph --noop manifest.pp
dot -Tpng /var/lib/puppet/state/graphs/relationships.dot -o relationships.png
Run Code Online (Sandbox Code Playgroud)

通过执行此操作,您将看到该类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'],
    ],
  }
}
Run Code Online (Sandbox Code Playgroud)