4

この 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

定義で current_resource が nil なのはなぜですかaction :alter???

4

1 に答える 1

3

ああ、とても近い!あなたのload_current_resource方法はまったく正しくありません。instance_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

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
于 2014-03-19T23:42:22.740 に答える