Module: Garcon::ChefHelpers

Extended by:
ChefHelpers
Includes:
Chef::Mixin::ShellOut
Included in:
ChefHelpers, Provider
Defined in:
lib/garcon/chef/chef_helpers.rb

Overview

More sweetness syntactical sugar for our Pâtissier.

Instance Method Summary collapse

Instance Method Details

#_?(*args, &block) ⇒ Boolean

Note:

‘_?` is defined on `Object`. Therefore, it won’t work with

Invokes the public method whose name goes as first argument just like ‘public_send` does, except that if the receiver does not respond to it the call returns `nil` rather than raising an exception.

instances of classes that do not have ‘Object` among their ancestors, like direct subclasses of `BasicObject`.

Parameters:

  • object (String)

    The object to send the method to.

  • method (Symbol)

    The method to send to the object.

Returns:



238
239
240
241
242
243
244
245
246
# File 'lib/garcon/chef/chef_helpers.rb', line 238

def _?(*args, &block)
  if args.empty? && block_given?
    yield self
  else
    resp = public_send(*args[0], &block) if respond_to?(args.first)
    return nil if resp.nil?
    !!resp == resp ? args[1] : [args[1], resp]
  end
end

#chef_nodeObject



33
34
35
36
37
# File 'lib/garcon/chef/chef_helpers.rb', line 33

def chef_node
  node = ::Chef::Node.new
  node.consume_external_attrs(nil, ohai)
  node
end

#chef_run_contextObject



29
30
31
# File 'lib/garcon/chef/chef_helpers.rb', line 29

def chef_run_context
  ::Chef::RunContext.new(chef_node, nil, nil)
end

#comma_separate(num) ⇒ String

Amazingly and somewhat surprisingly comma separate a number

Parameters:

  • num (Integer)

Returns:



301
302
303
# File 'lib/garcon/chef/chef_helpers.rb', line 301

def comma_separate(num)
  num.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
end

#cookbook_version(name = nil) ⇒ Integer

Retrieve the version number of the cookbook in the run list.

Parameters:

  • name (String) (defaults to: nil)

    name of cookbook to retrieve the version on.

Returns:

  • (Integer)

    version of the cookbook.



191
192
193
194
# File 'lib/garcon/chef/chef_helpers.rb', line 191

def cookbook_version(name = nil)
  cookbook = name.nil? ? cookbook_name : name
  node.run_context.cookbook_collection[cookbook]..version
end

#docker?Boolean

Returns true if the current node is a docker container, otherwise false.

Returns:



165
166
167
# File 'lib/garcon/chef/chef_helpers.rb', line 165

def docker?
  ::File.exist?('/.dockerinit') || ::File.exist?('/.dockerenv')
end

#file_cache_path(*args) ⇒ String

Shortcut to return cache path, if you pass in a file it will return the file with the cache path.

Examples:

file_cache_path
  => "/var/chef/cache/"

file_cache_path 'patch.tar.gz'
  => "/var/chef/cache/patch.tar.gz"

file_cache_path "#{node[:name]}-backup.tar.gz"
  => "/var/chef/cache/c20d24209cc8-backup.tar.gz"

Parameters:

  • args (String)

    name of file to return path with file

Returns:



215
216
217
218
219
220
221
# File 'lib/garcon/chef/chef_helpers.rb', line 215

def file_cache_path(*args)
  if args.nil?
    Chef::Config[:file_cache_path]
  else
    ::File.join(Chef::Config[:file_cache_path], args)
  end
end

#find_by(type, filter, single = true) { ... } ⇒ Array, Proc Also known as: find_matching

Search for a matching node by a given role or tag.

Parameters:

  • type (Symbol)

    The filter type, can be ‘:role` or `:tag`.

  • filter (String)

    The role or tag to filter on.

  • single (Boolean) (defaults to: true)

    True if we should return only a single match, or false to return all of the matches.

Yields:

  • an optional block to enumerate over the nodes.

Returns:

  • (Array, Proc)

    The value of the passed block or node.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/garcon/chef/chef_helpers.rb', line 78

def find_by(type, filter, single = true, &block)
  nodes = []
  env   = node.chef_environment
  type  = Inflections.pluralize(type.to_s)

  if node.public_send(type).include? filter
    nodes << node
  end
  if !single || nodes.empty?
    search(:node, "#{type}:#{filter} AND chef_environment:#{env}") do |n|
      nodes << n
    end
  end

  if block_given?
    nodes.each { |n| yield n }
  else
    single ? [nodes.first] : nodes
  end
end

#find_by_role(role, single = true) { ... } ⇒ Array, Proc Also known as: find_matching_role

Search for a matching node by role.

Parameters:

  • role (String)

    The role to filter on.

  • single (Boolean) (defaults to: true)

    True if we should return only a single match, or false to return all of the matches.

Yields:

  • an optional block to enumerate over the nodes.

Returns:

  • (Array, Proc)

    The value of the passed block or node.



114
115
116
# File 'lib/garcon/chef/chef_helpers.rb', line 114

def find_by_role(role, single = true, &block)
  find_matching :role, role, single, block
end

#find_by_tag(tag, single = true) { ... } ⇒ Array, Proc Also known as: find_matching_tag

Search for a matching node by tag.

Parameters:

  • tag (String)

    The role or tag to filter on.

  • single (Boolean) (defaults to: true)

    True if we should return only a single match, or false to return all of the matches.

Yields:

  • an optional block to enumerate over the nodes.

Returns:

  • (Array, Proc)

    The value of the passed block or node.



133
134
135
# File 'lib/garcon/chef/chef_helpers.rb', line 133

def find_by_tag(tag, single = true, &block)
  find_matching :tag, tag, single, block
end

#gem_installed?(gem = name) ⇒ Boolean

Boolean indicating if the given Ruby Gem is installed.

Parameters:

  • gem (String) (defaults to: name)

    The name of the Ruby Gem to check for.

Returns:

  • (Boolean)

    True if the Ruby Gem is installed, otherwise false.



56
57
58
# File 'lib/garcon/chef/chef_helpers.rb', line 56

def gem_installed?(gem = name)
  Gem::Specification.find_all_by_name(gem).blank? ? false : true
end

#has_source?(source, segment, cookbook = nil) ⇒ String, Nil

Checks for existence of a cookbook file or template source in a cookbook.

Examples:

has_source?("foo.erb", :templates)
has_source?("bar.conf", :files, "a_cookbook")

Parameters:

  • source (String)

    Name of the desired template or cookbook file source.

  • segment (Symbol)

    One of ‘:files` or `:templates`.

  • cookbook (String, Nil) (defaults to: nil)

    The name of the cookbook to look in, defaults to current cookbook.

Returns:

  • (String, Nil)

    Full path to the source or nil if it doesn’t exist.



266
267
268
269
270
271
272
273
274
275
# File 'lib/garcon/chef/chef_helpers.rb', line 266

def has_source?(source, segment, cookbook = nil)
  cookbook ||= cookbook_name
  begin
    run_context.cookbook_collection[cookbook].send(
      :find_preferred_manifest_record, run_context.node, segment, source
    )
  rescue Chef::Exceptions::FileNotFound
    nil
  end
end

#inspectString

Returns object inspection.

Returns:

  • (String)

    object inspection



351
352
353
354
355
356
357
358
359
# File 'lib/garcon/chef/chef_helpers.rb', line 351

def inspect
  instance_variables.inject([
    "\n#<#{self.class}:0x#{self.object_id.to_s(16)}>",
    "\tInstance variables:"
  ]) do |result, item|
    result << "\t\t#{item} = #{instance_variable_get(item)}"
    result
  end.join("\n")
end

#installed?(cmd) ⇒ TrueClass, FalseClass

Boolean method to check if a command line utility is installed.

Parameters:

  • cmd (String)

    The command to find.

Returns:



329
330
331
# File 'lib/garcon/chef/chef_helpers.rb', line 329

def installed?(cmd)
  !Garcon::FileHelper.which(cmd).nil?
end

#pkg_installed?(pkg) ⇒ TrueClass, FalseClass

Boolean method to check if a package is installed.

Parameters:

  • pkg (String)

    The package to check for.

Returns:



341
342
343
344
345
346
347
# File 'lib/garcon/chef/chef_helpers.rb', line 341

def pkg_installed?(pkg)
  if node.platform_family == 'debian'
    shell_out("dpkg -l #{pkg}").exitstatus == 0 ? true : false
  elsif node.platform_family == 'rhel'
    shell_out("rpm -qa | grep #{pkg}").exitstatus == 0 ? true : false
  end
end

#platform_recipesObject



39
40
41
42
43
44
45
46
# File 'lib/garcon/chef/chef_helpers.rb', line 39

def platform_recipes
  case node[:platform]
  when 'debian', 'ubuntu'
    run_context.include_recipe 'apt::default'
  when 'rhel'
    run_context.include_recipe 'yum-epel::default'
  end
end

#run_now(resource = nil) ⇒ Object

Adds a ‘run_now` method onto Resources so you can immediately execute the resource block. This is a shortcut so you do not have to set the action to :nothing, and then use the `.run_action` method with the desired action.

Examples:

service 'sshd' do
  action [:enable, :start]
end.run_now


151
152
153
154
155
156
157
# File 'lib/garcon/chef/chef_helpers.rb', line 151

def run_now(resource = nil)
  resource ||= self
  actions = Array(resource.action)
  Chef::Log.debug "Immediate execution of #{resource.name} #{actions}"
  resource.action(:nothing)
  actions.each { |action| resource.run_action(action) }
end

#selinux?Boolean

Returns true if the current node has selinux enabled, otherwise false.

Returns:



174
175
176
177
178
179
180
# File 'lib/garcon/chef/chef_helpers.rb', line 174

def selinux?
  if installed?('getenforce')
    Mixlib::ShellOut.new('getenforce').run_command.stdout != "Disabled\n"
  else
    false
  end
end

#to_sString

Returns string of instance.

Returns:

  • (String)

    string of instance



363
364
365
# File 'lib/garcon/chef/chef_helpers.rb', line 363

def to_s
  "<#{self.class}:0x#{self.object_id.to_s(16)}>"
end

#with_tmp_dir {|Proc| ... } ⇒ Object

Creates a temp directory executing the block provided. When done the temp directory and all it’s contents are garbage collected.

Yields:

  • (Proc)

    block A block that will be run

Returns:

  • (Object)

    Result of the block operation



315
316
317
318
319
# File 'lib/garcon/chef/chef_helpers.rb', line 315

def with_tmp_dir(&block)
  Dir.mktmpdir(SecureRandom.hex(3)) do |tmp_dir|
    Dir.chdir(tmp_dir, &block)
  end
end

#zip_hash(col1, col2) ⇒ Hash

Returns a hash using col1 as keys and col2 as values.

Examples:

zip_hash([:name, :age, :sex], [‘Earl’, 30, ‘male’])

=> { :age => 30, :name => "Earl", :sex => "male" }

Parameters:

  • col1 (Array)

    Containing the keys.

  • col2 (Array)

    Values for hash.

Returns:



290
291
292
# File 'lib/garcon/chef/chef_helpers.rb', line 290

def zip_hash(col1, col2)
  col1.zip(col2).inject({}) { |r, i| r[i[0]] = i[1]; r }
end