Puppet 依赖管理

Puppet dependancy management

假设我有一个 class 安装包 (profile::base::tools) 和另一个 class 定义这些包所需的 yumrepos(profile::base::yum)。

tools.pp:

class profile::base::tools {
   $packages = [
      'package1',
      'package2'
   ]

   package { $packages:
     ensure => present,
   }
}

目前运行是通过base.pp:

base.pp:

include profile::base::yum 
include profile::base::tools

Class['profile::base::yum'] -> [
    Class['profile::base::tools']]     

所以当我 运行 base.pp 它首先创建 yum repos 然后安装包。目前 tools.pp 需要先定义 yumrepos 的依赖只在 base.pp 中提到。

我的问题是,如果我 运行 tools.pp 单独(出于测试目的)它不会知道依赖关系,因此会失败。我可以在 tools.pp class 中添加 include profile::base::yum 但想知道它是否是每个 class 的标准以了解依赖项,即使它已经在其他地方定义(如 base.pp)

不清楚您实际上是如何进行测试的,但是如果您使用 Rspec,那么您可以为此使用 pre_conditionpost_condition,例如:

describe 'profile::base::tools' do
  let(:pre_condition) {
    """
    include profile::base::yum
    """
  }

  let(:post_condition) {
    """
    Class['profile::base::yum'] -> [
      Class['profile::base::tools']]
    """
  }

  it { is_expected.to contain_package('package1') }
  it { is_expected.to contain_package('package2') }
end

Rspec 然后在内部构建一个清单,其中 class 你 declare/test 包裹在前和 post 条件之间。

当然,你并不真的需要post条件;将两者都放在 pre_condition 中就可以了,因为此代码的顺序实际上并不重要,如下所示:

  let(:pre_condition) {
    """
    include profile::base::yum

    Class['profile::base::yum'] -> [
      Class['profile::base::tools']]
    """
  }

但是,如果您不使用 Rspec,并且您想手动或以其他自动方式测试它,原则是相同的:无论何时声明工具 class,也声明支持代码,包括依赖 class 和关系声明。

My question is if I run tools.pp alone(for testing purposes) it wont know about the dependency and hence fail. I can add include profile::base::yum in the tools.pp class but wanted to know if its a standard for each class to know about dependencies even if its already defined elsewhere(like in base.pp)

这是 public classes 和私有 classes 之间的主要区别之一。 Public classes 是那些供你模块的用户直接声明的,而 private classes 是那些应该只被其他 classes 声明的属于同一个模块。这种 public / private 区别本身主要是文档和约定的问题,但是尽管该语言没有直接支持 class 隐私,但 puppet/stdlib 模块确实 an assert_private function可以帮助您强制执行预期的使用模式。

对于私人 classes,所有这些细节都由您决定。这样的 classes 并不意味着直接声明,因此它们是否设置自己的依赖关系和关系并不重要。重要的是,当私有 class 由其模块的 public classes.

之一声明时,所有需要的依赖关系和关系都已设置。 另一方面,

Public classes 应该声明它们的所有依赖关系并在内部安排任何应用顺序要求。这确保您使用它们所需要做的就是自己声明它们。如何做到这一点有很多变化。在您的特定情况下,您当前在 profile::base class 中建立的关系可以通过使用 require 代替(或另外)在 profile::base::tools 中建立声明:

class profile::base::tools {
   # 'require' does everything 'include' does, plus establishes a relationship:
   require profile::base::yum

   # ...

}

因为尽可能具体地描述您的人际关系通常是个好主意,您也可以考虑更细化一些:

class profile::base::tools {
   include profile::base::yum

   $packages = [
      'package1',
      'package2'
   ]

   package { $packages:
     ensure  => present,
     require => Class['profile::base::yum'],
   }
}

这在这个特殊情况下没有实际区别,但在其他情况下可能有用。请注意,include yum::profile::base 仍然适用于确保它实际上已声明,即使与它的关系是在资源级别表示的。