尽管我知道昨天遇到的问题的直接解决方案(感谢 IRC #puppet 上的人们),但我仍然不明白它是如何解决问题的,或者更确切地说,在这个特定场景中类和定义之间的根本区别是什么:
原来的定义是不正确的:
define srv($name,$enable="true",$ensure="running",$provider="runit",$hasstatus="true",$hasrestart="true"){
exec {"sleep 5": path=>"/usr/bin:/usr/sbin:/bin:/sbin", before=>Service["$name"],}
service{"$name":
enable=>$enable,
ensure=>$ensure,
provider=>$provider,
hasstatus=>$hasstatus,
hasrestart=>$hasrestart,
}
}
错误:无法从远程服务器检索目录:服务器上的错误 400:重复定义:Exec[sleep 5] 已在文件 /etc/puppet/modules/common/manifests/defines/srv.pp 第 4 行中定义;无法在节点 testing.abc.def.com 上的 /etc/puppet/modules/common/manifests/defines/srv.pp:4 上重新定义
正确的定义:
define srv($enable="true",$ensure="running",$provider="runit",$hasstatus="true",$hasrestart="true"){
exec {"sleep 5 for $name": command=>"sleep 5", path=>"/usr/bin:/usr/sbin:/bin:/sbin", before=>Service["$name"],}
service{"$name":
enable=>$enable,
ensure=>$ensure,
provider=>$provider,
hasstatus=>$hasstatus,
hasrestart=>$hasrestart,
}
}
那么,为什么第一种情况下会出现错误?我怎么会重复定义?换句话说,如果有一个模块使用此定义,那么第一个定义会起作用吗?也许是文档中的傀儡术语让我感到困惑,但是我编写了大量(工作)模块却不理解这一点,这对我来说听起来很危险,希望我能得到一些明确的答案。
答案1
Puppet 中的资源必须是唯一的,即必须有一个唯一的名称。
Exec["sleep 5"]
在所述情况下,您在定义中 拥有资源,并且每次调用时srv
(它基本上与包含参数化类相同),该资源Exec["sleep 5"]
也将被包含在内,因此解析器会找到两个或多个具有相同名称的资源。
通过将$name
定义的名称附加到资源名称Exec
,您可以使其独一无二。至少最有可能的这是独一无二的,因为当您在清单中的其他地方有另一个同名资源(Exec["sleep 5 for foo"
)时,您会再次遇到此错误。