# Author:: Daniel DeLeo () # Copyright:: Copyright (c) 2009 Daniel DeLeo # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # module Shef class ShefSession include Singleton attr_accessor :node, :compile, :recipe, :run_context attr_reader :node_attributes, :client def initialize @node_built = false end def node_built? !!@node_built end def reset! loading do rebuild_node @node = client.node rebuild_context node.consume_attributes(node_attributes) if node_attributes shorten_node_inspect @recipe = Chef::Recipe.new(nil, nil, run_context) @node_built = true end end def node_attributes=(attrs) @node_attributes = attrs @node.consume_attributes(@node_attributes) end def resource_collection run_context.resource_collection end def run_context @run_context || rebuild_context end def definitions nil end def cookbook_loader nil end def save_node raise "Not Supported! #{self.class.name} doesn't support #save_node, maybe you need to run shef in client mode?" end def rebuild_context raise "Not Implemented! :rebuild_collection should be implemented by subclasses" end private def loading show_loading_progress begin yield rescue => e loading_complete(false) raise e else loading_complete(true) end end def show_loading_progress print "Loading" @loading = true @dot_printer = Thread.new do while @loading print "." sleep 0.5 end end end def loading_complete(success) @loading = false @dot_printer.join msg = success ? "done.\n\n" : "epic fail!\n\n" print msg end def shorten_node_inspect def @node.inspect "" end end def rebuild_node raise "Not Implemented! :rebuild_node should be implemented by subclasses" end end class StandAloneSession < ShefSession def rebuild_context @run_context = Chef::RunContext.new(@node, {}) # no recipes end private def rebuild_node Chef::Config[:solo] = true @client = Chef::Client.new @client.run_ohai @client.determine_node_name @client.build_node #(@client.node_name, true) end end class SoloSession < ShefSession def definitions @run_context.definitions end def rebuild_context @run_context = Chef::RunContext.new(@node, Chef::CookbookCollection.new(Chef::CookbookLoader.new)) end private def rebuild_node # Tell the client we're chef solo so it won't try to contact the server Chef::Config[:solo] = true @client = Chef::Client.new @client.run_ohai @client.determine_node_name @client.build_node #(@client.node_name, true) end end class ClientSession < SoloSession def save_node @client.save_node end private def rebuild_node # Make sure the client knows this is not chef solo Chef::Config[:solo] = false @client = Chef::Client.new @client.run_ohai @client.determine_node_name @client.register @client.build_node #(@client.node_name, false) @client.sync_cookbooks end end end