lib/soloist/config.rb
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