chef-infra - 为什么 LWRP 自定义定义给了我未定义的方法 nil :NilClass

标签 chef-infra chef-recipe chef-solo lwrp

我对此 LWRP 的自定义定义有问题。

资源:user_postgresql。

actions :create, :alter
default_action :create

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

提供者: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

改变行动 .
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

还有我的 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

这是错误:
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

为什么 action :alter 中的 current_resource 为零定义 ???

最佳答案

啊好近啊!您的 load_current_resource方法不太对。您需要设置 实例变量 ,但您只设置了一个局部变量:

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

我还将最初的创建移到了 begin 之外堵塞。即使出现故障,您仍然希望创建一个空资源。话虽如此,那个救援块是完全没有必要的。它应该只是:

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

关于chef-infra - 为什么 LWRP 自定义定义给了我未定义的方法 nil :NilClass,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22516424/

相关文章:

amazon-web-services - Chef : HOME environment variable (or HOMEDRIVE and HOMEPATH) must be set and point to a directory

automated-tests - 是否可以在不使用任何驱动程序的情况下对服务器运行厨房测试?

vagrant - 使用 Chef-solo 进行 precision64 vagrant box 配置失败

amazon-web-services - 测试 Recipe 时,Chef-Solo 在 Vagrant 中找不到设备错误

ruby - 错误 : Cookbook loaded at path(s) has invalid metadata

mysql - 如何在 Chef Ruby block 中执行 MySQL

chef-infra - 找不到 Chef Knife 命令404

chef-infra - Chef : No available formula with the name "httpd"

ruby - 如何在 Chef 中使用特殊字符?

linux - 无法通过公共(public)IP访问EC2 Linux实例上的站点