Class: Chef::Resource

Inherits:
Object show all
Extended by:
Mixin::ConvertToClassName
Includes:
Mixin::CheckHelper, Mixin::ConvertToClassName, Mixin::Language, Mixin::ParamsValidate
Defined in:
lib/chef/resource.rb,
lib/chef/resource/csh.rb,
lib/chef/resource/git.rb,
lib/chef/resource/scm.rb,
lib/chef/resource/bash.rb,
lib/chef/resource/cron.rb,
lib/chef/resource/file.rb,
lib/chef/resource/link.rb,
lib/chef/resource/perl.rb,
lib/chef/resource/ruby.rb,
lib/chef/resource/user.rb,
lib/chef/resource/group.rb,
lib/chef/resource/mdadm.rb,
lib/chef/resource/mount.rb,
lib/chef/resource/route.rb,
lib/chef/resource/deploy.rb,
lib/chef/resource/python.rb,
lib/chef/resource/script.rb,
lib/chef/resource/execute.rb,
lib/chef/resource/package.rb,
lib/chef/resource/service.rb,
lib/chef/resource/erl_call.rb,
lib/chef/resource/ifconfig.rb,
lib/chef/resource/template.rb,
lib/chef/resource/directory.rb,
lib/chef/resource/breakpoint.rb,
lib/chef/resource/ruby_block.rb,
lib/chef/resource/subversion.rb,
lib/chef/resource/apt_package.rb,
lib/chef/resource/gem_package.rb,
lib/chef/resource/remote_file.rb,
lib/chef/resource/dpkg_package.rb,
lib/chef/resource/http_request.rb,
lib/chef/resource/deploy_revision.rb,
lib/chef/resource/portage_package.rb,
lib/chef/resource/macports_package.rb,
lib/chef/resource/remote_directory.rb,
lib/chef/resource/timestamped_deploy.rb,
lib/chef/resource/easy_install_package.rb

Defined Under Namespace

Classes: AptPackage, Bash, Breakpoint, Cron, Csh, Deploy, DeployBranch, DeployRevision, Directory, DpkgPackage, EasyInstallPackage, ErlCall, Execute, File, GemPackage, Git, Group, HttpRequest, Ifconfig, Link, MacportsPackage, Mdadm, Mount, Package, Perl, PortagePackage, Python, RemoteDirectory, RemoteFile, Route, Ruby, RubyBlock, Scm, Script, Service, Subversion, Template, TimestampedDeploy, User

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mixin::ConvertToClassName

convert_to_class_name, convert_to_snake_case, filename_to_qualified_string

Methods included from Mixin::Language

#data_bag, #data_bag_item, #platform?, #search, #value_for_platform

Methods included from Mixin::ParamsValidate

#set_or_return, #validate

Methods included from Mixin::CheckHelper

#set_if_args

Constructor Details

#initialize(name, collection = nil, node = nil) ⇒ Resource

Returns a new instance of Resource.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/chef/resource.rb', line 38

def initialize(name, collection=nil, node=nil)
  @name = name
  if collection
    @collection = collection
  else
    @collection = Chef::ResourceCollection.new()
  end      
  @node = node ? node : Chef::Node.new
  @noop = nil
  @before = nil
  @actions = Hash.new
  @params = Hash.new
  @provider = nil
  @allowed_actions = [ :nothing ]
  @action = :nothing
  @updated = false
  @supports = {}
  @ignore_failure = false
  @not_if = nil
  @only_if = nil
  sline = caller(4).shift
  if sline
    @source_line = sline.gsub!(/^(.+):(.+):.+$/, '\1 line \2')
    @source_line = ::File.expand_path(@source_line) if @source_line
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_symbol, *args, &block) ⇒ Object

If an unknown method is invoked, determine whether the enclosing Provider’s lexical scope can fulfill the request. E.g. This happens when the Resource’s block invokes new_resource.



68
69
70
71
72
73
74
# File 'lib/chef/resource.rb', line 68

def method_missing(method_symbol, *args, &block)
  if enclosing_provider && enclosing_provider.respond_to?(method_symbol)
    enclosing_provider.send(method_symbol, *args, &block)
  else
    raise NoMethodError, "undefined method `#{method_symbol.to_s}' for #{self.class.to_s}"
  end
end

Instance Attribute Details

#actionsObject

Returns the value of attribute actions.



35
36
37
# File 'lib/chef/resource.rb', line 35

def actions
  @actions
end

#allowed_actionsObject

Returns the value of attribute allowed_actions.



35
36
37
# File 'lib/chef/resource.rb', line 35

def allowed_actions
  @allowed_actions
end

#collectionObject

Returns the value of attribute collection.



35
36
37
# File 'lib/chef/resource.rb', line 35

def collection
  @collection
end

#cookbook_nameObject

Returns the value of attribute cookbook_name.



35
36
37
# File 'lib/chef/resource.rb', line 35

def cookbook_name
  @cookbook_name
end

#enclosing_providerObject

Returns the value of attribute enclosing_provider.



35
36
37
# File 'lib/chef/resource.rb', line 35

def enclosing_provider
  @enclosing_provider
end

#nodeObject (readonly)

Returns the value of attribute node.



36
37
38
# File 'lib/chef/resource.rb', line 36

def node
  @node
end

#paramsObject

Returns the value of attribute params.



35
36
37
# File 'lib/chef/resource.rb', line 35

def params
  @params
end

#provider(arg = nil) ⇒ Object

Returns the value of attribute provider.



35
36
37
# File 'lib/chef/resource.rb', line 35

def provider
  @provider
end

#recipe_nameObject

Returns the value of attribute recipe_name.



35
36
37
# File 'lib/chef/resource.rb', line 35

def recipe_name
  @recipe_name
end

#resource_nameObject (readonly)

Returns the value of attribute resource_name.



36
37
38
# File 'lib/chef/resource.rb', line 36

def resource_name
  @resource_name
end

#source_lineObject (readonly)

Returns the value of attribute source_line.



36
37
38
# File 'lib/chef/resource.rb', line 36

def source_line
  @source_line
end

#updatedObject

Returns the value of attribute updated.



35
36
37
# File 'lib/chef/resource.rb', line 35

def updated
  @updated
end

Class Method Details

.attribute(attr_name, validation_opts = {}) ⇒ Object



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/chef/resource.rb', line 258

def attribute(attr_name, validation_opts={})
  # This atrocity is the only way to support 1.8 and 1.9 at the same time
  # When you're ready to drop 1.8 support, do this:
  # define_method attr_name.to_sym do |arg=nil|
  # etc.
  shim_method=<<-SHIM
  def #{attr_name}(arg=nil)
    _set_or_return_#{attr_name}(arg)
  end
  SHIM
  class_eval(shim_method)
  
  define_method("_set_or_return_#{attr_name.to_s}".to_sym) do |arg|
    set_or_return(attr_name.to_sym, arg, validation_opts)
  end
end

.build_from_file(cookbook_name, filename) ⇒ Object



275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/chef/resource.rb', line 275

def build_from_file(cookbook_name, filename)
  rname = filename_to_qualified_string(cookbook_name, filename)
    
  new_resource_class = Class.new self do |cls|
    
    # default initialize method that ensures that when initialize is finally
    # wrapped (see below), super is called in the event that the resource
    # definer does not implement initialize
    def initialize(name, collection=nil, node=nil)
      super(name, collection, node)
    end
    
    @actions_to_create = []
    
    class << cls
      include Chef::Mixin::FromFile
      
      def actions_to_create
        @actions_to_create
      end
      
      define_method(:actions) do |*action_names|
        actions_to_create.push(*action_names)
      end
    end
    
    # load resource definition from file
    cls.class_from_file(filename)
    
    # create a new constructor that wraps the old one and adds the actions
    # specified in the DSL
    old_init = instance_method(:initialize)

    define_method(:initialize) do |name, *optional_args|
      collection = optional_args.shift
      node = optional_args.shift
      @resource_name = rname.to_sym
      old_init.bind(self).call(name, collection, node)
      allowed_actions.push(self.class.actions_to_create).flatten!
    end
  end
  
  # register new class as a Chef::Resource
  class_name = convert_to_class_name(rname)
  Chef::Resource.const_set(class_name, new_resource_class)
  Chef::Log.debug("Loaded contents of #{filename} into a resource named #{rname} defined in Chef::Resource::#{class_name}")
  
  new_resource_class
end

.json_create(o) ⇒ Object



248
249
250
251
252
253
254
# File 'lib/chef/resource.rb', line 248

def json_create(o)
  resource = self.new(o["instance_vars"]["@name"])
  o["instance_vars"].each do |k,v|
    resource.instance_variable_set(k.to_sym, v)
  end
  resource
end

.provider_base(arg = nil) ⇒ Object

Resources that want providers namespaced somewhere other than Chef::Provider can set the namespace with provider_base Ex:

class MyResource < Chef::Resource
  provider_base Chef::Provider::Deploy
  # ...other stuff
end


332
333
334
335
# File 'lib/chef/resource.rb', line 332

def provider_base(arg=nil)
  @provider_base ||= arg
  @provider_base ||= Chef::Provider
end

Instance Method Details

#action(arg = nil) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/chef/resource.rb', line 112

def action(arg=nil)
  if arg
    action_list = arg.kind_of?(Array) ? arg : [ arg ]
    action_list = action_list.collect { |a| a.to_sym }
    action_list.each do |action|
      validate(
        {
          :action => action,
        },
        {
          :action => { :kind_of => Symbol, :equal_to => @allowed_actions },
        }
      )
    end
    @action = action_list
  else
    @action
  end
end

#epic_fail(arg = nil) ⇒ Object



154
155
156
# File 'lib/chef/resource.rb', line 154

def epic_fail(arg=nil)
  ignore_failure(arg)
end

#ignore_failure(arg = nil) ⇒ Object



146
147
148
149
150
151
152
# File 'lib/chef/resource.rb', line 146

def ignore_failure(arg=nil)
  set_or_return(
    :ignore_failure,
    arg,
    :kind_of => [ TrueClass, FalseClass ]
  )
end

#is(*args) ⇒ Object



193
194
195
# File 'lib/chef/resource.rb', line 193

def is(*args)
  return *args
end

#load_prior_resourceObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/chef/resource.rb', line 76

def load_prior_resource
  begin
    prior_resource = @collection.lookup(self.to_s)
    Chef::Log.debug("Setting #{self.to_s} to the state of the prior #{self.to_s}")
    prior_resource.instance_variables.each do |iv|
      unless iv == "@source_line" || iv == "@action"
        self.instance_variable_set(iv, prior_resource.instance_variable_get(iv))
      end
    end
    true
  rescue ArgumentError => e
    true
  end
end

#name(name = nil) ⇒ Object



132
133
134
135
136
137
# File 'lib/chef/resource.rb', line 132

def name(name=nil)
  set_if_args(@name, name) do
    raise ArgumentError, "name must be a string!" unless name.kind_of?(String)
    @name = name
  end
end

#noop(tf = nil) ⇒ Object



139
140
141
142
143
144
# File 'lib/chef/resource.rb', line 139

def noop(tf=nil)
  set_if_args(@noop, tf) do 
    raise ArgumentError, "noop must be true or false!" unless tf == true || tf == false
    @noop = tf
  end
end

#not_if(arg = nil, &blk) ⇒ Object



231
232
233
234
235
236
237
238
# File 'lib/chef/resource.rb', line 231

def not_if(arg=nil, &blk)
  if Kernel.block_given?
    @not_if = blk
  else
    @not_if = arg if arg
  end
  @not_if
end

#notifies(*args) ⇒ Object

Raises:

  • (ArgumentError)


158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/chef/resource.rb', line 158

def notifies(*args)
  raise ArgumentError, "Wrong number of arguments (should be 1, 2, or 3)" unless ( args.size > 0 && args.size < 4)
  if args.size > 1
    notifies_helper(*args)
  else
    resources_array = *args
    resources_array.each do |resource|
      resource.each do |key, value|
        notifies_helper(value[0], key, value[1])    
      end
    end 
  end
end

#only_if(arg = nil, &blk) ⇒ Object



222
223
224
225
226
227
228
229
# File 'lib/chef/resource.rb', line 222

def only_if(arg=nil, &blk)
  if Kernel.block_given?
    @only_if = blk
  else
    @only_if = arg if arg
  end
  @only_if
end

#resources(*args) ⇒ Object



172
173
174
# File 'lib/chef/resource.rb', line 172

def resources(*args)
  @collection.resources(*args)
end

#run_action(action) ⇒ Object



240
241
242
243
244
# File 'lib/chef/resource.rb', line 240

def run_action(action)
  provider = Chef::Platform.provider_for_node(@node, self)
  provider.load_current_resource
  provider.send("action_#{action}")
end

#subscribes(action, resources, timing = :delayed) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/chef/resource.rb', line 176

def subscribes(action, resources, timing=:delayed)
  timing = check_timing(timing)
  rarray = resources.kind_of?(Array) ? resources : [ resources ]
  rarray.each do |resource|
    action_sym = action.to_sym
    if resource.actions.has_key?(action_sym)
      resource.actions[action_sym][timing] << self
    else       
      resource.actions[action_sym] = Hash.new
      resource.actions[action_sym][:delayed] = Array.new
      resource.actions[action_sym][:immediate] = Array.new   
      resource.actions[action_sym][timing] << self
    end
  end
  true
end

#supports(args = {}) ⇒ Object



91
92
93
94
95
96
97
# File 'lib/chef/resource.rb', line 91

def supports(args={})
  if args.any?
    @supports = args
  else
    @supports
  end
end

#to_hashObject



214
215
216
217
218
219
220
# File 'lib/chef/resource.rb', line 214

def to_hash
  instance_vars = Hash.new
  self.instance_variables.each do |iv|
    instance_vars[iv.sub(/^@/,'').to_sym] = self.instance_variable_get(iv) unless iv == "@collection"
  end
  instance_vars
end

#to_json(*a) ⇒ Object

Serialize this object as a hash



202
203
204
205
206
207
208
209
210
211
212
# File 'lib/chef/resource.rb', line 202

def to_json(*a)
  instance_vars = Hash.new
  self.instance_variables.each do |iv|
    instance_vars[iv] = self.instance_variable_get(iv) unless iv == "@collection"
  end
  results = {
    'json_class' => self.class.name,
    'instance_vars' => instance_vars
  }
  results.to_json(*a)
end

#to_sObject



197
198
199
# File 'lib/chef/resource.rb', line 197

def to_s
  "#{@resource_name}[#{@name}]"
end