问题
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