Created
December 7, 2013 05:00
-
-
Save markolson/7837491 to your computer and use it in GitHub Desktop.
Pass a environment name, node name, and path to a JSON file with a run_list in it, and get back a node that you can call merged_attributes on to get (pretty dang close to) what the node will have as it's attributes during a run. Useful for updating docs to have up-to-date with a pre-commit hook.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# I'm sure this can all be replaced with a one liner, buried deep in chef somewhere. | |
# Actually, probably Chef::Client. | |
require 'json' | |
require 'chef' | |
require 'chef/application/solo' | |
require 'chef/knife/deps' | |
def setup_node(environment, name, node_config_path) | |
Chef::Config[:config_file] = ".chef/knife.rb" | |
Chef::Config[:solo] = true | |
# load the environment, which gives paths to cookbooks and environments | |
env = Chef::ConfigFetcher.new(Chef::Config[:config_file]) | |
Chef::Config.from_string(env.read_config, Chef::Config[:config_file]) | |
# setup some config after loading the config file.. | |
Chef::Config[:environment] = environment | |
Chef::Config[:node_name] = name | |
# Loads up all the bookbooks in our path | |
cl = Chef::CookbookLoader.new(Chef::Config[:cookbook_path]) | |
cl.load_cookbooks | |
# Create a node -- this also loads up environment config | |
node = Chef::Node.build(name) | |
# OHAI is needed. It will provide data from your laptop, but we don't | |
# show/use the data this provides in any of our attributes | |
ohai = ::Ohai::System.new | |
ohai.all_plugins | |
automatic = ohai.data | |
# lies | |
automatic['platform_family'] = 'debian' | |
# lies, lies | |
automatic['lsb'] = {'codename' => 'precise'} | |
automatic['memory'] = {'total' => '4096'} # awwyiss fake memory for our one node | |
node.automatic_attrs.merge! automatic | |
# This loads up the run list from the node file | |
node.consume_run_list(JSON.load(File.read(node_config_path))) | |
# And expands out the roles to all of their recipes | |
full_run_list = node.expand!('disk') | |
# Iterate over all the recipes in the runlist, which can be either "cookbook" or | |
# "cookbook::subrecipe" -- we only want "cookbook" | |
cookbooks = full_run_list.recipes.map {|recipe| | |
# sets the short cookbook name | |
original = recipe =~ /(.+)::[^:]*/ ? $1 : recipe | |
# load all the "depends" from metadata as well. | |
dependencies = cl[original].metadata.dependencies.keys | |
# return both | |
[original, dependencies] | |
}.flatten.uniq # flatten and uniq the array. | |
# do some bookkeeping to setup a run context, which is used to keep track of | |
# which dependencies have already been loaded. | |
events = Chef::EventDispatch::Dispatcher.new | |
cookbook_collection = Chef::CookbookCollection.new(cl) | |
run_context = Chef::RunContext.new(node, cookbook_collection, events) | |
# This loads the attributes for each cookbook into the node | |
compiler = Chef::RunContext::CookbookCompiler.new(run_context, full_run_list, events) | |
compiler.compile_libraries | |
compiler.compile_resource_definitions | |
compiler.compile_lwrps | |
compiler.compile_attributes | |
node | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment