【问题标题】:Puppet dependancy managementPuppet 依赖管理
【发布时间】:2018-08-29 05:30:11
【问题描述】:

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

工具.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 存储库,然后安装软件包。目前tools.pp需要先定义yumrepos的依赖只在base.pp中提到。

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

【问题讨论】:

  • 你应该在tools类中使用require yum而不是Class['profile::base::yum'] -> Class['profile::base::tools']puppet.com/docs/puppet/5.5/…
  • 见cmets到下面的答案

标签: dependencies puppet standards


【解决方案1】:

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

这是公共类和私有类之间的主要区别之一。公共类是那些打算让您的模块的用户直接声明的类,而私有类是那些应该只由属于同一模块的其他类声明的类。这种公有/私有区别本身主要是文档和约定的问题,但尽管该语言没有直接支持类隐私,但 puppet/stdlib 模块确实有 an assert_private function 可以帮助您执行预期的使用模式。

对于私人课程,所有这些细节都由您决定。这样的类并不意味着直接声明,因此它们是否设置自己的依赖关系和关系并不重要。重要的是,当私有类由其模块的公共类之一声明时,所有需要的依赖项和关系都已设置。

另一方面,公共类应该声明它们的所有依赖项并在内部安排任何要设置的应用程序要求。这确保了使用它们所需要做的就是声明它们自己。如何做到这一点有很多变化。在您的特定情况下,您当前在profile::base 类中设置的关系可以通过使用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'],
   }
}

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

【讨论】:

  • 绝对同意粒度依赖映射。这有助于减少由于隐式资源包含而导致的循环依赖的变化,并且通常是更好的实践。整个答案都有很好的最佳实践信息,assert_private 是一个非常有用的功能,可以防止我们的开发人员经常忘记使用类滥用。
【解决方案2】:

不清楚您实际上是如何进行测试的,但如果您使用的是 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 然后在内部构建一个清单,其中包含您声明/测试的类,包装在前置条件和后置条件之间。

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

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

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

如果你不使用 Rspec,但是你想手动或以其他自动化方式测试,原理是一样的:每当你声明工具类时,也要声明支持代码,包括依赖类和关系声明。

【讨论】:

  • 我了解如何将它们一起运行。我的问题更多地是关于一个类应该知道它的依赖关系而不考虑测试的想法。这带来了额外的优势,即规范在测试时不需要关心依赖关系,因为类知道它们。这是错的吗?
  • 我看到了它的优势,但这不是 Puppet 的工作方式。类之间的关系,无论好坏,都存在于类之外。
  • 此外,您的规范测试在对它们进行单元测试时不应该需要关心它们的依赖关系。我已经展示了如何做到这一点,以防你确实需要这样做,出于某种未指定的原因,例如如果一个类依赖于另一个类中的资源。
  • '类之间的关系,无论好坏,都存在于类之外':你是说让类知道其依赖关系是一种不好的做法还是根本不可能?我想如果我在tools.pp 中添加include profile::base::yum 会使其成为tools.pprequire profile::base::yum 中的依赖项
  • 我应该补充一点,如果您的意思是require function,那么根据上面的答案,您是正确的。根据您的符号,我认为您的意思是 require => Class[yum] 即元参数需要。
猜你喜欢
  • 2021-11-18
  • 2021-09-09
  • 2011-03-13
  • 2013-06-15
  • 2011-11-24
  • 2010-09-13
  • 2011-09-04
  • 2011-07-09
相关资源
最近更新 更多