Можно ли включить Chef `include_recipe` и указать условие `only_if`/not_if`?

Я хочу, чтобы include_recipe only_if было выполнено какое-то условие. Следующий код не вызывает никаких ошибок, но и не заботится об условии only_if, поэтому выполняется в любом случае:

include_recipe "cubrid" do
    only_if "hostname | grep 'blahblahshouldnotmatch'"
end

Возможно ли include_recipe только при некоторых условиях?


person Eye    schedule 12.04.2013    source источник


Ответы (4)


include_recipe — это не обычные ресурсы в Chef, а обычный метод. Из-за этого он игнорирует переданный блок и впоследствии указанное там условие only_if.

К счастью, для этого есть решение. Пользователь flaccid с канала #chef freenode предложил следующее решение, которое отлично работает.

this_node_is_shard_broker = node["hostname"].include? "node2"
include_recipe "cubrid" if this_node_is_shard_broker

Вышеприведенное выполнит include_recipe только в том случае, если имя хоста текущего работающего узла node2, и это именно то, чего я хотел добиться.

person Eye    schedule 12.04.2013
comment
include_recipe кажется обычным вызовом функции ruby, поэтому вы можете использовать простой ruby ​​if <condition> <code> end. - person cmur2; 12.04.2013

Это работает просто отлично:

include_recipe "foo" if node['bar'] == 'baz'
person Chris Gianelloni    schedule 14.05.2015

Вышеупомянутое не сработало для меня, но сработало следующее:

if node["hostname"].include? "node2"
  include_recipe "cubrid"
end
person semirami    schedule 24.04.2015

Во всех ответах, которые предполагают

include_recipe "foo" if node['bar'] == 'baz'

вы забываете одну чрезвычайно важную вещь - это, если оценивается на этапе компиляции, и если узел ['bar'] изменяется в ходе выполнения, это если даст неправильный результат, поскольку он будет основан на оригинале, а не на измененном ценность.

Можно возразить, что это плохая практика, но подумайте дважды, прежде чем делать это. Просто пример: установка пакетов в режиме шеф-клиента — обычная практика. После этого перезагрузить пакеты плагинов ohai можно считать хорошей практикой, но что произойдет с кодом:

include_recipe "my_cookbook::install" unless node['packages'].key?('mypackage')

в случае, если мой пакет установлен где-то в поваренной книге, которая выполняется ранее в том же запуске клиента? Правильный ответ — рецепт будет включен, хотя из кода ясно, что ожидается, что это не так.

К сожалению, я, по крайней мере, не знаю, как решить эту проблему, так как и include_recipe, и возможное условие оцениваются на этапе компиляции. Насколько я знаю, нет способа условного включения рецепта на основе действий, предпринятых другими кулинарными книгами в рамках одного и того же запуска шеф-клиента.

person Stanislav    schedule 08.03.2019
comment
Я думаю, что если вы действительно хотите сделать рецепт зависимым от атрибута, который может измениться во время запуска Chef, ваш единственный вариант — сделать каждый ресурс в рецепте условным. Но это довольно редкий вариант использования. Чаще всего хотелось бы передать строку в only_if, которая будет интерпретирована пользовательским интерпретатором, и теперь придется вручную выполнять работу по вызову этого интерпретатора и извлечению логического значения из его вывода. Неудобно, но в целом приемлемо. - person Zeust the Unoobian; 28.01.2020