我可以通过在子shell中调用knife
来检索cookbook列表(然后解析输出),例如:
cb = `knife cookbook list`
另一种方法是直接调用ruby类/模块,例如:
require("chef")
require("chef/knife")
Chef::Config.from_file(knifePath) #knifePath is declared a priori
cookbooks = Chef::Knife.run(["cookbook", "list"])
puts(cookbooks) # => nil
如何通过将Chef::Knife.run()
调用到变量中来存储打印在屏幕上的数据?
答案 0 :(得分:0)
你需要在knife
之外寻找这个。 Knife委托给Chef::CookbookLoader
(在堆栈下面),因此你可以直接使用cookbook loader:
require 'chef/config'
require 'chef/cookbook_loader'
Chef::Config.from_file(path)
cookbooks = Chef::CookbookLoader.new(Chef::Config.cookbook_path).map(&:cookbook_name)
例如,knife-spork
使用此模式加载cookbook。
请注意,您将获得实际的cookbook对象,而不仅仅是他们的名字。如果你想要一些更轻量级的东西,你可以迭代每个cookbook_path
并寻找metadata.rb
:
# https://gist.github.com/fnichol/4343327
class MetadataChopper < Hash
def self.extract(metadata_file)
mc = new(File.expand_path(metadata_file))
[mc[:name], mc[:version]]
end
def initialize(metadata_file)
eval(IO.read(metadata_file), nil, metadata_file)
end
def method_missing(meth, *args, &block)
self[meth] = args.first
end
end
require 'chef/config'
cookbook_paths = Chef::Config.from_file(path).cookbook_path
cookbooks = Dir[*cookbook_paths.map { |p| "#{p}/**/metadata.rb" }].collect do |metadata|
MetadataChopper.new(metadata)[:name] || File.basename(File.dirname(cookbook))
end