ruby - List cookbook dynamically without sub-shell -
i can retrieve cookbook list invoking knife
in sub-shell (and parse output) such as:
cb = `knife cookbook list`
another approach invoking ruby classes/modules directly such as:
require("chef") require("chef/knife") chef::config.from_file(knifepath) #knifepath declared priori cookbooks = chef::knife.run(["cookbook", "list"]) puts(cookbooks) # => nil
how can store data printed on screen calling chef::knife.run()
variable?
you need outside of knife
one. knife delegates chef::cookbookloader
(lower down stack) , therefore can use cookbook loader directly:
require 'chef/config' require 'chef/cookbook_loader' chef::config.from_file(path) cookbooks = chef::cookbookloader.new(chef::config.cookbook_path).map(&:cookbook_name)
for example, knife-spork
uses pattern load cookbooks.
note actual cookbook objects, not names. if want little more lightweight, iterate on each 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 |metadata| metadatachopper.new(metadata)[:name] || file.basename(file.dirname(cookbook)) end
Comments
Post a Comment