我看到this question用户遇到了同样的问题,但我没有问同样的问题。
我在puppet中遇到与其他OP相同的循环依赖问题。导致此错误的原因是我们使用的内置锚定的上游模块是有意义的,但与我们在manifests / site.pp中使用的上游apt模块的组件的锚定方式不兼容,以确保更新在添加新来源时运行。
manifest / site.pp中的puppet代码确保在apt更新之前运行任何apt源,这在安装任何软件包之前发生,是:
Apt::Source <| |> -> Class['apt::update'] -> Package <| |>
上游docker模块与此不兼容,具体而言,repo.pp puppet清单的this line正在将一个包锚定在apt源之前,如下所示:
Package['apt-transport-https'] -> Apt::Source <||>
因此出现了合法的周期性依赖循环。
显然我可以通过更新上游模块兼容(已被其他人打开作为问题here来修复此问题,因此显然也是其他人的问题),或更新我们在清单中的锚定/site.pp将其删除并添加每个适当的模块/包(yuck)。
我更感兴趣的解决方案,无论是为了解决这个具体问题,还是为了更好地理解木偶清单,如果有办法设置清单/ site.pp那么apt源的具体锚定模式,apt update和package(上面引用)仅在某些范围内发生。
类似于用于打开诸如hostname:
之类的东西的if
逻辑
if $hostname !~ /^myhostname/ {}
有没有办法在puppet中引用类/范围而不是关于节点的事实/变量?这段代码不起作用,但我在寻找理论上的东西:
if scope != 'docker' {
Apt::Source <| |> -> Class['apt::update'] -> Package <| |>
}
或者,如果没有办法做到这一点,我会说明木偶清单包含适用于整个节点的事物的逻辑(例如主机名,内存,CPU数量)以及所包含的资源是否正确对于整个编译清单,而ruby函数可以包含更多关于木偶执行范围的特定逻辑吗?
答案 0 :(得分:1)
[有]设置清单/ site.pp的方法所以apt源,apt更新和包(上面引用)的特定锚定模式只发生在某些范围内[?]
首先,您不应该声明Apt::Source
资源与Class['apt::update']
之间的关系,至少如果这些资源来自puppetlabs-apt模块则不应该。应该足够的是,该类不是模块的公共类 - 因此模块外部的代码应该永远不会触及它。此外,该模块已经注意管理它提供的类和资源类型之间的关系,你不应该这样做。换句话说,你太努力了。
事实上,这基本上是让你陷入困境的原因。您插入site.pp
的链式表达式过于宽泛,涵盖了除了您希望覆盖的第三方模块之外的第三方模块的资源。
如果您要问如何更具体,那么您应该考虑在收集器表达式中使用filter predicate。例如:
Exec['apt-update'] -> Package<| tag == 'docker' |>
(请注意,puppetlabs-apt模块记录Exec['apt-update']
的存在和可用性,这使得使用起来相当安全。)
如上所示,有时与tags很好地匹配,但您可能会发现Puppet的自动标记覆盖的资源比适合您的目的更多,并且必须手动标记您的资源会使目的失败。
或者,如果没有办法做到这一点,我会说明木偶清单包含适用于整个节点的事物的逻辑(例如主机名,内存,CPU数量)以及所包含的资源是否正确对于整个编译清单,而ruby函数可以包含更多关于木偶执行范围的特定逻辑吗?
这听起来太宽泛而且太模糊。
所有类和资源声明都具有全局可见性和效果。同样,收集者收集资源,无论声明出现的范围如何,或者在目录构建期间评估这些声明的相对顺序。
在目录构建期间评估清单代码。它可以依赖节点事实,对目录构建器可用的外部数据进行自定义,以便为目标节点构建目录。它还可以依赖硬编码到您的清单中的数据,但本身很难被视为“自定义”。
Puppet支持各种类型的Ruby插件,具有各种范围,角色和功能。从技术上讲,他们可以访问Puppet内部,因为它们在Puppet的整体Ruby上下文中运行,但是他们不应该这样做。一般来说,Ruby插件应该将自己限制为与清单代码可用的基本相同的信息。或者更少。