У меня есть небольшое приложение, установленное на нескольких серверах, я хотел написать быстрый рецепт, который позволит мне получить номер версии с этих серверов.
Вот что я написал:
bash "Get app version" do
code <<-EOH
cat /var/lib/myapp/node_modules/myapp/package.json | grep version
EOH
end
Однако, когда я запускаю команду Knife bootstrap, я не вижу вывода в моей консоли, даже если я запускаю ее с помощью -VV
выхода нет.
У меня два вопроса:
cat
результаты появляются в моей консоли?Сохраните номер версии как атрибут узла. Таким образом, у вас есть центральное хранилище версий, и вы можете легко использовать атрибут node в другом месте в Chef.
Что-то вроде:
ruby_block "myapp installed version check" do
block do
# file setup
file = "/var/lib/myapp/node_modules/myapp/package.json"
raise "File doesn't exist [#{file}]" unless File.exists?( file )
# get the version line
versions = open( file ).grep(/version/)
raise "No versions in file [#{file}]" unless versions.length > 0
Chef::Log.warn "Too many versions [#{versions.length}] in file [#{file}]" unless versions.length == 1
# some regex to match your version number
version = versions[0].match(/\d+\.\d+/).to_s
# set the attribute
node.set[:installed][:myapp][:version] = version
# optionally reload node so attribute is available during this chef-client run
node.from_file( run_context.resolve_attribute('myapp-cookbook', 'default') )
# and log it.
Chef::Log.info( "myapp version is [#{node[:installed][:myapp][:version]}]" )
end
end
raise
приведет к сбою выполнения Chef за исключением. Использовать Chef::Log
и return
вместо этого для ошибок, которые не являются критическими и вы хотите продолжить обработку рецептов.
Вы можете удалить биты атрибутов узла и просто зарегистрировать информацию, чтобы она отображалась в журнале chef-client. Это немного лучше, чем полагаться на stdout / stderr, который исчезает, когда chef-client не работает в интерактивном режиме (то есть как служба). Но зачем просто регистрировать это, если вы можете хранить его в центральном месте и запрашивать значение через вашу инфра?
нота обычно лучше реализовать рубин в библиотека и использовать его через настраиваемый легкий ресурс если вы когда-нибудь подумаете, что повторно воспользуетесь этой функцией для myapp-b.
Во-первых, чтобы увидеть результат на выходе вашего ножа, вам может потребоваться перенаправить stdout
вывод на stderr
, что является противоположностью обычной идиомы:
cat /var/lib/myapp/node_modules/myapp/package.json | grep version 1>&2
Но если вы просто выполнили свою исходную команду, используя ssh
(или распространяется с помощью такого инструмента, как dsh
) вместо ножа вы получите желаемый результат без накладных расходов или дополнительной производительности, связанной с проходом ножа.
Что касается «наилучшего способа» сбора данных, это полностью зависит от того, для чего вы хотите их использовать. Если это просто информационное сообщение и вы хотите его увидеть, когда вы выполняете операцию начальной загрузки вручную, то использование ножа таким образом может быть нормальным. Но если вы хотите что-то систематически делать с данными, например, собирать их и использовать в другой программе, то использование ножа вряд ли будет лучшим способом сделать это.