木偶给出错误:“非法关系操作数,无法与Undef值形成关系”

问题描述

运行时:

$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],}
}

仅在有条件的情况下将元参数放在资源上,即可提供仅在声明该资源时才声明的关系。而且,它简单明了。