Why does the LWRP custom definition gives me undefined method for nil:NilClass

蹲街弑〆低调 提交于 2019-12-22 08:40:11

问题


I have problem with my custom definition of this LWRP.

resources : user_postgresql.

actions :create, :alter
default_action :create

attribute :username, :kind_of => String
attribute :password, :kind_of => String
attribute :database_name,  :kind_of => String

providers : user_postgresql.

def whyrun_supported?
  true
end

action :create do
  converge_by "Create [#{new_resource}]" do

    USER_NAME     = new_resource.username
    USER_PASSWORD = new_resource.password unless (new_resource.password.nil? ||
                                                        new_resource.password.empty?)
    USER_PASSWORD = USER_NAME
    DATABASE_NAME = new_resource.database_name unless (new_resource.database_name.nil? ||
                                                              new_resource.database_name.empty?)
    DATABASE_NAME = USER_NAME

    execute "create user [#{USER_NAME}]" do
      user "postgres"
      exists = <<-EOH
      PGPASSWORD='postgres' psql -U postgres -c "select * from pg_user where usename='#{USER_NAME}'" | grep -c #{USER_NAME}
      EOH
      command "PGPASSWORD='postgres' createuser -U postgres -sw #{USER_NAME}"
      not_if exists, :user => "postgres"
    end

    execute "set-password" do
      user "postgres"
      command "PGPASSWORD='postgres' psql -U postgres -c \"alter role #{USER_NAME} with password '#{USER_PASSWORD}'\""
    end

    execute "create-database" do
      user "postgres"
      exists = <<-EOH
      PGPASSWORD='postgres' psql -U postgres -c "select * from pg_database WHERE datname='#{DATABASE_NAME}'" | grep -c #{DATABASE_NAME}
      EOH
      command "PGPASSWORD='postgres' createdb -U postgres -O #{USER_NAME} -T template0 #{DATABASE_NAME}"
      not_if exists, :user => "postgres"
    end
  end
  new_resource.updated_by_last_action(true)    
end

And the alter action.

action :alter do

  converge_by "Alter user password" do
    execute "alter-password" do
      user "postgres"
      command "psql -U postgres -c \"alter role #{current_resource.username} with password '#{current_resource.password}';\""
    end
  end
  current_resource.updated_by_last_action(true)
end

And my load_current_resource:

def load_current_resource
  begin
    current_resource = Chef::Resource::AppCookbookUserPostgresql.new(new_resource.name)
    current_resource.name(new_resource.name)
    current_resource.username(new_resource.username)
    current_resource.password(new_resource.password)
    current_resource.database_name(new_resource.database_name)
    current_resource
  rescue
    Chef::Log.debug("Cannot find #{new_resource} in the swarm")
  end
end

And it is the error:

Error executing action `alter` on resource 'app_cookbook_user_postgresql[change password to user postgres]'       
================================================================================       


NoMethodError       
-------------       
undefined method `username' for nil:NilClass       


Cookbook Trace:       
---------------       
/tmp/kitchen/cookbooks/app_cookbook/providers/user_postgresql.rb:53:in `block (2 levels) in class_from_file'       
/tmp/kitchen/cookbooks/app_cookbook/providers/user_postgresql.rb:52:in `block in class_from_file'       


Resource Declaration:       
---------------------       
# In /tmp/kitchen/cookbooks/app_cookbook/recipes/postgresql.rb       

 31: app_cookbook_user_postgresql 'change password to user postgres' do       
 32:   username 'postgres'       
 33:   action :alter       
 34: end       
 35:        



Compiled Resource:       
------------------       
# Declared in /tmp/kitchen/cookbooks/app_cookbook/recipes/postgresql.rb:31:in `from_file'       

app_cookbook_user_postgresql("change password to user postgres") do       
  action [:alter]       
  retries 0       
  retry_delay 2       
  cookbook_name :app_cookbook       
  recipe_name "postgresql"       
  username "postgres"       
end

Why does the current_resource is nil in the action :alter definition ???


回答1:


Ahh so close! Your load_current_resource method isn't quite right. You need to set the instance_variable, but you've only set a local variable:

def load_current_resource
  @current_resource = Chef::Resource::AppCookbookUserPostgresql.new(new_resource.name)

  begin
    @current_resource.name(new_resource.name)
    @current_resource.username(new_resource.username)
    @current_resource.password(new_resource.password)
    @current_resource.database_name(new_resource.database_name)
    @current_resource
  rescue
    Chef::Log.debug("Cannot find #{new_resource} in the swarm")
  end
end

I've also moved the initial creation outside of the begin block. You still want to create an empty resource, even if something fails. That being said, that rescue block is entirely unnecessary. It should just be:

def load_current_resource
  @current_resource = Chef::Resource::AppCookbookUserPostgresql.new(new_resource.name)
  @current_resource.username(new_resource.username)
  @current_resource.password(new_resource.password)
  @current_resource.database_name(new_resource.database_name)
  @current_resource
end


来源:https://stackoverflow.com/questions/22516424/why-does-the-lwrp-custom-definition-gives-me-undefined-method-for-nilnilclass

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!