0

我可以通过调用knife子外壳(然后​​解析输出)来检索食谱列表,例如:

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()变量来存储打印在屏幕上的数据?

4

1 回答 1

0

你需要在外面knife寻找这个。Knife 委托给Chef::CookbookLoader(降低堆栈),因此您可以直接使用说明书加载器:

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_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
于 2013-08-08T18:57:56.963 回答