Search code examples
rubychef-infralwrp

Chef LWRP "undefined method 'checkname' for nil:NilClass"


I'm trying to write an LWRP for a Chef cookbook and I'm running into a strange issue where this property seems to be perfectly valid on one line, and the nil the next.

From the provider code, error on the source line:

def create_check
  cookbook_file get_check_filename(@current_resource.checkname) do
    source  "checks/#{@current_resource.checkname}" # undefined method `checkname' for nil:NilClass
    mode    '0644'
    action  :create
  end
end

and the load_current_resource method just to show that it is initialized:

def load_current_resource
  @current_resource = Chef::Resource::OmdCheck.new(@new_resource_name)
  @current_resource.checkname(@new_resource.checkname) # right here!
  @current_resource.sitename(@new_resource.sitename)
  @current_resource.sitecfgroot(sprintf(CMK_CFGROOT_FRM, @new_resource.sitename))
  @current_resource.perfometer(@new_resource.perfometer)
  @current_resource.pnptemplate(@new_resource.pnptemplate)

  @current_resource.exists = check_exists?(@current_resource.checkname)
end

Any help is much appreciated.


Solution

  • So I got an answer on #chef:

    <@coderanger> Sammitch: Use current_resource, not @current_resource
    < Sammitch> it's passed in as an instance var?
    <@coderanger> Sammitch: No, its actually a method on Provider
    <@coderanger> as is new_resource
    <@coderanger> the issue is that the block on a resource is evaluated against the resource object
    <@coderanger> So in there, @foo is looking at an ivar on the new resource object
    <@coderanger> _but_ there is some magic
    <@coderanger> Chef::Resource has a method_missing to forward unknown method calls to the enclosing provider
    <@coderanger> So #current_resource gets forwarded up for you
    <@coderanger> Basically never use the ivar form
    <@coderanger> Always new_resource and current_resource instead
    <@coderanger> and it will mostly JFW
    

    And I'm pretty green as far as Ruby and Chef go, so only like 20% of that made sense to me, but I amended my code to the below and it works:

    def create_check
      cookbook_file get_check_filename(@current_resource.checkname) do
        source  "checks/#{current_resource.checkname}" # removed the @
        mode    '0644'
        action  :create
      end
    end