#puppet
#кукольный
Вопрос:
При запуске этого:
$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],
}
}
Кукольный выдает ошибку «Ошибка: Ошибка оценки: недопустимый операнд связи, не может сформировать связь со значением Undef. Требуется тип каталога. (файл: /tmp/test-fails.pp, строка: 22, столбец: 5) на узле instance.example.com «, где строка 22, столбец 5 — это тильда в ~>
.
Ответ №1:
Проблема находится в правой части ~>
оператора. В частности, поскольку 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,
}
}
Таким образом, Puppet не только не запишет файл, если ramdisk не смонтирован, он удалит любую копию, созданную другими методами.
Комментарии:
1. Предлагаемый код не выражает то, что, по-видимому, намеревается OP. Управление отсутствием файла — это совсем не то же самое, что оставить его неуправляемым.
2. TBH, мне действительно все равно, есть ли файл или нет, когда ram-диск не смонтирован. Но я не хочу, чтобы кукольный устанавливал его, если не ramdisk. Это было что-то, что нужно было сделать. Ваш другой ответ верен, но я не нашел хороших результатов Google для упомянутого сообщения об ошибке и хотел увековечить мои выводы об ошибке.
Ответ №2:
Хотя 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],
}
}
Добавление метапараметра к ресурсу, который включен только условно, дает вам связь, которая объявляется только тогда, когда этот ресурс объявлен. Кроме того, это просто и понятно.