问题描述
运行时:
$ramdisk = '/never-save-to-disk'
$keyfile = "${ramdisk}/test.key"
$encryption_key = undef
file {
[
$ramdisk,]:
ensure => directory,owner => 'root',group => 'root',}
mount { $ramdisk:
ensure => 'mounted',device => 'null',fstype => 'ramfs',options => 'defaults',dump => 0,pass => 0,}
~> if ($encryption_key != undef) and ($encryption_key != '') {
file { $keyfile:
content => $encryption_key,path => $keyfile,owner => 'database',group => 'database',mode => '0600',require => File[$ramdisk],}
}
Puppet给出错误“错误:评估错误:非法关系操作数,无法与Undef值形成关系。目录类型是必需的。(文件:/tmp/test-fails.pp,第22行,列:5)在节点instance.example.com上,其中第22行第5列是~>
中的波浪号。
解决方法
问题出在~>
运算符的右侧。具体来说,由于if
失败,它将创建undef
值。解决方法是确保有一个else
子句,例如对于这种情况:
~> if ($encryption_key != undef) and ($encryption_key != '') {
file { $keyfile:
content => $encryption_key,path => $keyfile,owner => 'database',group => 'database',mode => '0600',require => File[$ramdisk],}
} else {
file { $keyfile:
ensure => absent,}
}
因此,如果未安装ramdisk,Puppet不仅不会写入文件,还会删除其他方法创建的副本。
,尽管if
语句确实会产生值,但是这些值不一定是~>
运算符的合适右手操作数。特别是,undef
将是您的if
语句的条件值为false
时产生的值,并且对于任何链接运算符都不可接受。
有几种方法可以解决该问题,其中某些方法取决于您的实际意图,但是就样式而言,我认为使用if
语句作为链接的操作数是一种较差的形式在任何情况下都是箭头。
如果确实确实仅在条件满足时才想管理文件$keyfile
(如您的示例所示),那么最自然的解决方案是使用适当的关系元参数而不是链接箭头:
mount { $ramdisk:
# ...
}
# no chaining arrow here
if ($encryption_key != undef) and ($encryption_key != '') {
file { $keyfile:
# ...
require => File[$ramdisk],# Like this:
subscribe => Mount[$ramdisk],}
}
仅在有条件的情况下将元参数放在资源上,即可提供仅在声明该资源时才声明的关系。而且,它简单明了。