Class: PoolParty::Chef

Inherits:
Base show all
Defined in:
lib/poolparty/chef.rb

Direct Known Subclasses

ChefClient, ChefSolo

Constant Summary collapse

BOOTSTRAP_PACKAGES =
%w( ruby ruby1.8-dev libopenssl-ruby1.8 rdoc
ri irb build-essential wget ssl-cert rubygems git-core rake
librspec-ruby libxml-ruby zlib1g-dev libxml2-dev )
BOOTSTRAP_GEMS =

thin couchdb

%w( chef )
BOOTSTRAP_BINS =

we dont specifically install these binaries, they installed by packages and gems above, but we check for them

%w( gem chef-solo chef-client )
BOOTSTRAP_DIRS =
%w( /var/log/chef /var/cache/chef /var/run/chef )

Instance Attribute Summary

Attributes inherited from Base

#name

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#after_initialized, #initialize, #run

Constructor Details

This class inherits a constructor from PoolParty::Base

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &block) ⇒ Object (private)



142
143
144
145
146
147
148
# File 'lib/poolparty/chef.rb', line 142

def method_missing(m,*args,&block)
  if cloud.respond_to?(m)
    cloud.send(m,*args,&block)
  else
    super
  end
end

Class Method Details

.get_chef(type, cloud, &block) ⇒ Object



23
24
25
# File 'lib/poolparty/chef.rb', line 23

def self.get_chef(type,cloud,&block)
  ("Chef" + type.to_s.capitalize).constantize(PoolParty).send(:new,type,:cloud => cloud,&block)
end

.typesObject



19
20
21
# File 'lib/poolparty/chef.rb', line 19

def self.types
  return [:solo,:client]
end

Instance Method Details

#attributes(hsh = {}, &block) ⇒ Object

Chef



28
29
30
# File 'lib/poolparty/chef.rb', line 28

def attributes(hsh={}, &block)
  @attributes ||= ChefAttribute.new(hsh, &block)
end

#compile!Object



15
16
17
# File 'lib/poolparty/chef.rb', line 15

def compile!
  build_tmp_dir
end

#node_bootstrap!(remote_instance, force = false) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/poolparty/chef.rb', line 107

def node_bootstrap!(remote_instance, force=false)
  return if !force && node_bootstrapped?(remote_instance)

  # TODO: this should not be hardcoded (like in node_run)
  deb_gem_bin='/var/lib/gems/1.8/bin'
  gem_src='http://gems.opscode.com'

  bootstrap_cmds =
    [
     'apt-get update',
     'apt-get autoremove -y',
     'apt-get install -y %s' % BOOTSTRAP_PACKAGES.join(' '),
     "gem source -l | grep -q #{gem_src} || gem source -a #{gem_src} ",
     'gem install %s --no-rdoc --no-ri' % 
        (BOOTSTRAP_GEMS + remote_instance.bootstrap_gems).join(' '),
     "apt-get install -y %s" % BOOTSTRAP_PACKAGES.join(' '),
     "[ -d #{deb_gem_bin} ] && ln -sf #{deb_gem_bin}/* /usr/local/bin",
     "mkdir -p %s" % BOOTSTRAP_DIRS.join(' ')
    ]

  remote_instance.ssh(bootstrap_cmds)
end

#node_bootstrapped?(remote_instance, quiet = true) ⇒ Boolean

Returns:

  • (Boolean)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/poolparty/chef.rb', line 87

def node_bootstrapped?(remote_instance, quiet=true)
  # using which command instead of calling gem directly.  On
  # ubuntu, calling a command from package not installed
  # 'helpfully' prints message, which result confuses detection
  #
  cmd = "which %s" % BOOTSTRAP_BINS.join(' ') +
    " && dpkg -l %s " % BOOTSTRAP_PACKAGES.join(' ') +
    BOOTSTRAP_GEMS.map{ |gem|
      "&& gem search '^#{gem}$' | grep -v GEMS | wc -l | grep -q 1"
    }.join(' ') +
    BOOTSTRAP_DIRS.map{ |dir|
      "&& [[ -d #{dir} ]] "
    }.join(' ') +
    (quiet ? " >/dev/null " : "" ) +
    " && echo OK || echo MISSING"

  r = remote_instance.ssh(cmd, :do_sudo => false )
  r.lines.to_a.last.chomp == "OK"
end

#node_configure!(remote_instance) ⇒ Object



83
84
85
# File 'lib/poolparty/chef.rb', line 83

def node_configure!(remote_instance)
  # nothing in the superclass
end

#node_run!(remote_instance) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/poolparty/chef.rb', line 66

def node_run!(remote_instance)
  node_stop!(remote_instance)
  node_configure!(remote_instance)

  envhash = {
    :GEM_BIN => %q%$(gem env | grep "EXECUTABLE DIRECTORY" | awk "{print \\$4}")%
  }
  cmds = chef_cmd
  cmds = [cmds] unless cmds.respond_to? :each

  remote_instance.ssh(cmds.map{|c| c.strip.squeeze(' ')}, :env => envhash )
end

#node_stop!(remote_instance) ⇒ Object



79
80
81
# File 'lib/poolparty/chef.rb', line 79

def node_stop!(remote_instance)
  remote_instance.ssh("killall -q chef-client chef-solo; [ -f /etc/init.d/chef-client ] && invoke-rc.d chef-client stop")
end

#override_attributes(hsh = {}, &block) ⇒ Object



32
33
34
# File 'lib/poolparty/chef.rb', line 32

def override_attributes(hsh={}, &block)
  @override_attributes ||= ChefAttribute.new(hsh, &block)
end

#recipe(recipe_name, hsh = {}) ⇒ Object

Adds a chef recipe to the cloud

The hsh parameter is inserted into the override_attributes. The insertion is performed as follows. If the recipe name = “foo::bar” then effectively the call is

override_attributes.merge! { :foo => { :bar => hsh } }



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/poolparty/chef.rb', line 43

def recipe(recipe_name, hsh={})
  _recipes << recipe_name unless _recipes.include?(recipe_name)

  head = {}
  tail = head
  recipe_name.split("::").each do |key|
    unless key == "default"
      n = {}
      tail[key] = n
      tail = n
    end
  end
  tail.replace hsh

  override_attributes.merge!(head) unless hsh.empty?
end

#recipes(*recipes) ⇒ Object



60
61
62
63
64
# File 'lib/poolparty/chef.rb', line 60

def recipes(*recipes)
  recipes.each do |r|
    recipe(r)
  end
end