我在一些服务器上安装了一个小应用程序,我想编写一个快速方法,让我能够从这些服务器收集版本号。
这是我写的:
bash "Get app version" do
code <<-EOH
cat /var/lib/myapp/node_modules/myapp/package.json | grep version
EOH
end
但是,当我运行 knife bootstrap 命令时,我没有在控制台中看到输出,即使我运行它也-VV
没有输出。
我有两个问题:
- 这是我收集版本号的最佳方式吗?
- 为什么结果没有
cat
出现在我的控制台中?
答案1
保存版本号为节点属性。这样,您就拥有了版本的中央存储,并且可以轻松地在 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 未以交互方式运行时(即作为服务),stdout/stderr 会消失。但是,为什么只记录它,而您可以将其存储在中心位置并在整个基础设施中查询值呢?
答案2
首先,要查看 knife 输出中的输出,您可能需要将输出重定向stdout
到stderr
,这与通常的习惯用法相反:
cat /var/lib/myapp/node_modules/myapp/package.json | grep version 1>&2
ssh
但是如果您只是使用(或使用类似的工具分发)而不是 knife 来运行原始命令dsh
,那么您将获得所需的输出,而无需 knife 运行的开销或额外输出。
至于收集数据的“最佳方式”,这完全取决于你想用它做什么。如果它只是信息性的,并且希望在执行手动引导操作时看到它,那么以这种方式使用刀可能没问题。但是如果你想要系统地处理数据,比如收集它并在另一个程序中使用它,那么使用刀可能不是最好的方法。