Module: Garcon::ChefHelpers

Extended by:
ChefHelpers
Includes:
Chef::DSL::IncludeRecipe, 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:



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

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



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

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

#chef_run_contextObject



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

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:



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

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.



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

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:



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

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:



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

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.



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

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.



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

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.



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

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.



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

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.



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

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



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

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:



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

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:



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

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



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

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


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

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:



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

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



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

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



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

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:



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

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