Skip to content

Instantly share code, notes, and snippets.

@omgitsads
Forked from cliffdickerson/shef.rb
Created February 24, 2012 11:45
Show Gist options
  • Save omgitsads/1900436 to your computer and use it in GitHub Desktop.
Save omgitsads/1900436 to your computer and use it in GitHub Desktop.
Shef - chef in irb
$ bin/shef
Loading Node Data
Ohai2u!
chef > recipe
=> :recipe
chef:recipe > file "/tmp/foo"
=> #<Chef::Resource::File:0x1c3cd2c @provider=nil, @not_if=nil, @params={}, @recipe_name=nil, @action="create", @source_line="/Users/danielsdeleo/ruby/shef/(irb) line 2", @actions={}, @ignore_failure=false, @name="/tmp/foo", @cookbook_name=nil, @enclosing_provider=nil, @resource_name=:file, @before=nil, @supports={}, @backup=5, @allowed_actions=[:nothing, :create, :delete, :touch, :create_if_missing], @path="/tmp/foo", @only_if=nil, @noop=nil, @updated=false, @node=eigenstate.local, @collection=#<Chef::ResourceCollection:0x1c4f328 @insert_after_idx=nil, @resources=[#<Chef::Resource::File:0x1c3cd2c ...>], @resources_by_name={"file[/tmp/foo]"=>0}>>
chef:recipe > run_chef
[Tue, 03 Nov 2009 22:16:27 -0700] DEBUG: Processing file[/tmp/foo]
[Tue, 03 Nov 2009 22:16:27 -0700] DEBUG: file[/tmp/foo] using Chef::Provider::File
[Tue, 03 Nov 2009 22:16:27 -0700] INFO: Creating file[/tmp/foo] at /tmp/foo
=> 1
chef:recipe > file "/tmp/bar"
=> #<Chef::Resource::File:0x1c37a5c @provider=nil, @not_if=nil, @params={}, @recipe_name=nil, @action="create", @source_line="/Users/danielsdeleo/ruby/shef/(irb) line 4", @actions={}, @ignore_failure=false, @name="/tmp/bar", @cookbook_name=nil, @enclosing_provider=nil, @resource_name=:file, @before=nil, @supports={}, @backup=5, @allowed_actions=[:nothing, :create, :delete, :touch, :create_if_missing], @path="/tmp/bar", @only_if=nil, @noop=nil, @updated=false, @node=eigenstate.local, @collection=#<Chef::ResourceCollection:0x1c4f328 @insert_after_idx=1, @resources=[#<Chef::Resource::File:0x1c3cd2c @provider=nil, @not_if=nil, @params={}, @recipe_name=nil, @action="create", @source_line="/Users/danielsdeleo/ruby/shef/(irb) line 2", @actions={}, @ignore_failure=false, @name="/tmp/foo", @cookbook_name=nil, @enclosing_provider=nil, @resource_name=:file, @before=nil, @supports={}, @backup=5, @allowed_actions=[:nothing, :create, :delete, :touch, :create_if_missing], @path="/tmp/foo", @only_if=nil, @noop=nil, @updated=true, @node=eigenstate.local, @collection=#<Chef::ResourceCollection:0x1c4f328 ...>>, #<Chef::Resource::File:0x1c37a5c ...>], @resources_by_name={"file[/tmp/foo]"=>0, "file[/tmp/bar]"=>1}>>
chef:recipe > run_chef
[Tue, 03 Nov 2009 22:16:47 -0700] DEBUG: Processing file[/tmp/foo]
[Tue, 03 Nov 2009 22:16:47 -0700] DEBUG: file[/tmp/foo] using Chef::Provider::File
[Tue, 03 Nov 2009 22:16:48 -0700] DEBUG: Processing file[/tmp/bar]
[Tue, 03 Nov 2009 22:16:48 -0700] DEBUG: file[/tmp/bar] using Chef::Provider::File
[Tue, 03 Nov 2009 22:16:48 -0700] INFO: Creating file[/tmp/bar] at /tmp/bar
=> 1
chef:recipe >
# Launch this from an executable file containing:
#
# #!/usr/bin/env ruby
# exec "irb -r irb/completion -r lib/shef"
#
require "singleton"
require "pp"
require "rubygems"
require "chef"
require "chef/client"
module Shef
class IRBContext < Hash
include Singleton
def initialize
reset!
end
def reset!
puts "Loading Node Data"
self[:client] = Chef::Client.new
self[:client].build_node('localhost', true)
node = self[:node] = self[:client].node
def node.inspect(verbose=false)
if verbose
super()
else
"<Chef::Node:0x#{self.object_id.to_s(16)} @name=\"#{self.name}\">"
end
end
self[:recipe] = Chef::Recipe.new(nil, nil, self[:node])
end
end
module IRBExtension
def select_subsession(context_type)
unless jobs.respond_to?(:select_shef)
def jobs.select_shef(context_type)
Array(@jobs.select { |job| job[1].context.main.kind_of?(context_type)}.first)[1]
end
end
jobs.select_shef(context_type)
end
def shef_context
IRBContext.instance
end
def self.echo_mode=(on_off)
@echo_mode = on_off
end
def self.echo_mode
@echo_mode = true if @echo_mode.nil?
@echo_mode
end
def self.desc(text)
@desc = text
end
def self.method_added(mname)
if @desc
help_text[mname.to_s] = @desc.to_s
@desc = nil
end
end
def self.help_text
@help_text ||= {}
end
desc "prints this help message"
def shef_help
puts "Shef Help"
puts "".ljust(80, "=")
puts "| " + "Command".ljust(20) + "| " + "Description"
puts "".ljust(80, "=")
::Shef::IRBExtension.help_text.each do |cmd, description|
puts "| " + cmd.ljust(20) + "| " + description
end
puts "".ljust(80, "=")
:youcanhaz_helpz
end
desc "switch to recipe mode"
def recipe
if subsession = select_subsession(::Chef::Recipe)
jobs.switch(subsession)
else
irb(shef_context[:recipe])
end
:recipe
end
desc "switch to attributes mode"
def attributes
if subsession = select_subsession(::Chef::Node)
jobs.switch(subsession)
else
irb(shef_context[:node])
end
:attributes
end
desc "turn tracing on or off"
def trace(on_off=nil)
return trace? if on_off.nil?
on_off = true if on_off.to_s == "on"
on_off = false if on_off.to_s == "off"
puts "This is going to be verbose..." if on_off
conf.use_tracer = on_off
trace?
end
alias :tracing :trace
desc "show whether tracing is on or off"
def trace?
puts begin
"tracing = #{conf.use_tracer ? "on" : "off"}"
rescue NoMethodError
"tracing = off"
end
end
alias :tracing? :trace?
desc "turn console echo/object inspection on/off"
def echo(on_off=nil)
return echo? if on_off.nil?
on_off = true if on_off.to_s == "on"
on_off = false if on_off.to_s == "off"
IRBExtension.echo_mode = on_off
conf.echo = on_off
echo?
end
desc "show if console echo is on or off"
def echo?
"echo = #{conf.echo ? "on" : "off"}"
end
desc "the current node, i.e. this host"
def node
shef_context[:node]
end
desc "pretty print the node's attributes"
def ohai
pp node.attribute
end
desc "run chef with the configured recipe"
def run_chef
Chef::Log.level(:debug)
runrun = Chef::Runner.new(node, shef_context[:recipe].collection).converge
Chef::Log.level(:info)
end
desc "reset the session with a blank recipe and reload node data"
def reset
shef_context.reset!
jobs.switch(select_subsession(Object))
:reset
end
desc "pretty print the resources for the current recipe"
def resources
pp shef_context[:recipe].collection.instance_variable_get(:@resources_by_name).keys
end
end
end
Shef::IRBContext.instance
Shef::GREETING = begin
" #{Etc.getlogin}@#{Shef::IRBContext.instance[:node].name}"
rescue NameError
""
end
Object.send(:include, Shef::IRBExtension)
IRB.conf[:HISTORY_FILE] = "~/.shef_history"
IRB.conf[:SAVE_HISTORY] = 1000
IRB.conf[:PROMPT][:CHEF] = { :PROMPT_C => "chef > ",
:AUTO_INDENT => true,
:RETURN => " => %s \n",
:PROMPT_I => "chef > ",
:PROMPT_N => "chef ?> ",
:PROMPT_S => "chef%l> "}
IRB.conf[:PROMPT_MODE] = :CHEF
IRB.conf[:IRB_RC] = lambda do |conf|
m = conf.main
leader = case m
when Chef::Recipe
":recipe"
when Chef::Node
":attributes"
else
""
end
def m.help
shef_help
end
conf.echo = Shef::IRBExtension.echo_mode
conf.prompt_c = "chef#{leader} > "
conf.return_format = " => %s \n"
conf.prompt_i = "chef#{leader} > "
conf.prompt_n = "chef#{leader} ?> "
conf.prompt_s = "chef#{leader}%l> "
end
puts "Ohai2u#{Shef::GREETING}!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment