我有三个位于单独文件中的模块清单(精简到只剩基本内容):
class users {
$user = 'foo'
user { $user:
ensure => present;
}
}
class dvcs_cli {
require users
file { "/home/${::users::user}/.gitconfig":
ensure => present,
source => 'puppet:///modules/dvcs_cli/.gitconfig';
}
}
class shell {
require users
file { "/home/${::users::user}/.bash_aliases":
ensure => present,
source => 'puppet:///modules/shell/bash_aliases.sh';
}
}
.gitconfig
/home/foo
是按预期创建的,但是.bash_aliases
创建于/home
:
$ sudo /usr/bin/puppet apply --modulepath modules --detailed-exitcodes --hiera_config=hieradata/hiera.yaml manifests/host.pp || [ $? -eq 2 ]
[…]
Notice: /Stage[main]/Shell/File[/home//.bash_aliases]/ensure: defined content as '{md5}[…]'
Notice: /Stage[main]/Shell/File[/home/foo/.gitconfig]/ensure: defined content as '{md5}[…]'
就好像${::users::user}
在一个模块中计算为空字符串,但在另一个模块中则不然。这怎么可能?
运行--debug
揭示了一个可能的问题:User[foo]
是自动必需的dvcs_cli
,但不是shell
:
$ grep 'Adding autorequire relationship with User' puppet.log | grep -i -e dvcs_cli -e shell
Debug: /Stage[main]/Dvcs_cli/File[/home/pair/.gitconfig]: Adding autorequire relationship with User[pair]
这与手动的,其中说:
如果 Puppet 正在管理拥有文件的用户或组,则文件资源将自动需要它们。
这可能与“Autorequire 关系是不透明的”,由于两个文件位于同一目录中而导致?既然两个模块都明确表示,那么 autorequires 不应该是无关紧要的吗require users
?
跑步
$ puppet --version
4.2.1
在
$ cat /etc/redhat-release
Fedora release 24 (Twenty Four)
答案1
我在一个奇怪的情况下遇到了这个,对我来说,这是 Puppet 默默地打破了一个循环,但不是以可预测的方式(也不是在--debug
输出中)。我以前见过一次这种行为,但在其他一些变化之后它就“消失了”,所以我从来没有真正理解过。
设想:
class a {
include b
$foo = 'quick'
$bar = $b::baz
}
class b {
include a
$baz = 'brown'
if ($hostname == $baz) {
$qux = $a::foo
}
}
这$bar
是在改变了包含和有条件的undef
类之后的情况- 但两者都没有受到影响。这似乎是不正确的行为。c
a
b
a
b
解决方法是:
class b {
$baz = 'brown'
if ($hostname == $baz) {
include a
$qux = $a::foo
}
}
然后$bar
又被定义了。有一种方法可以用点文件可视化循环,但我还没有深入研究它。
Puppet 5.5.22(Debian 稳定版)