require "soloist/royal_crown" require "tempfile" module Soloist class Config attr_writer :solo_rb_path, :node_json_path attr_reader :royal_crown def self.from_file(royal_crown_path) rc = Soloist::RoyalCrown.from_file(royal_crown_path) new(rc) end def initialize(royal_crown) @royal_crown = royal_crown end def run_chef exec(conditional_sudo("bash -c '#{chef_solo}'")) end def chef_solo "chef-solo -c '#{solo_rb_path}' -l '#{log_level}'" end def as_solo_rb <<-SOLO_RB file_cache_path "#{chef_cache_path}" cookbook_path #{cookbook_paths.inspect} json_attribs "#{node_json_path}" SOLO_RB end def as_node_json compiled.node_attributes.to_hash.merge({ "recipes" => compiled.recipes }) end def chef_cache_path "/var/chef/cache".tap do |cache_path| system(conditional_sudo("mkdir -p #{cache_path}")) \ unless File.directory?(cache_path) end end def cookbook_paths ([royal_crown_cookbooks_directory] + compiled.cookbook_paths).map do |path| File.expand_path(path, royal_crown_path) end.uniq.select do |path| File.directory?(path) end end def solo_rb_path @solo_rb_path ||= Tempfile.new(["solo", ".rb"]).tap do |file| puts as_solo_rb if debug? file.write(as_solo_rb) file.close end.path end def node_json_path @node_json_path ||= Tempfile.new(["node", ".json"]).tap do |file| puts JSON.pretty_generate(as_node_json) if debug? file.write(JSON.dump(as_node_json)) file.close end.path end def merge!(other) royal_crown.recipes += other.royal_crown.recipes royal_crown.cookbook_paths += other.royal_crown.cookbook_paths royal_crown.node_attributes.merge!(other.royal_crown.node_attributes) royal_crown.env_variable_switches.merge!(other.royal_crown.env_variable_switches) end def compiled @compiled ||= royal_crown.dup.tap do |working_royal_crown| while working_royal_crown["env_variable_switches"] working_royal_crown.delete("env_variable_switches").each do |variable, switch| switch.each do |value, inner| working_royal_crown.merge!(inner) if ENV[variable] == value end end end end end def log_level ENV["LOG_LEVEL"] || "info" end def debug? log_level == "debug" end private def conditional_sudo(command) root? ? command : "sudo -E #{command}" end def root? Process.uid == 0 end def royal_crown_cookbooks_directory File.expand_path("cookbooks", royal_crown_path) end def royal_crown_path File.dirname(royal_crown.path) end end end