sous-chefs / sc-mongodb

Development repository for the sc-mongodb cookbook
https://supermarket.chef.io/cookbooks/sc-mongodb
Apache License 2.0
75 stars 92 forks source link

Undefined local variable or method `rs_member_ips' for Chef::ResourceDefinitionList::MongoDB:Class #189

Closed UncleIS closed 6 years ago

UncleIS commented 6 years ago

Hello, colleagues.

I'm using sc-mongodb::replicaset recipe to configure a replicaset of three MongoDB servers. The first run does just fine and the RS is configured as expected, but subsequent runs fail:

    Error executing action `run` on resource 'ruby_block[config_replicaset]'
    ================================================================================

    NameError
    ---------
    undefined local variable or method `rs_member_ips' for Chef::ResourceDefinitionList::MongoDB:Class

    Cookbook Trace:
    ---------------
    /tmp/chef-zero340752472/local-mode-cache/cache/cookbooks/sc-mongodb/libraries/mongodb.rb:135:in `configure_replicaset'
    /tmp/chef-zero340752472/local-mode-cache/cache/cookbooks/sc-mongodb/definitions/mongodb.rb:246:in `block (3 levels) in from_file'

    Resource Declaration:
    ---------------------
    # In /tmp/chef-zero340752472/local-mode-cache/cache/cookbooks/sc-mongodb/definitions/mongodb.rb

    244:     ruby_block 'config_replicaset' do
    245:       block do
    246:         MongoDB.configure_replicaset(node, replicaset_name, rs_nodes) unless new_resource.replicaset.nil?
    247:       end
    248:       action :nothing
    249:     end
    250:

    Compiled Resource:
    ------------------
    # Declared in /tmp/chef-zero340752472/local-mode-cache/cache/cookbooks/sc-mongodb/definitions/mongodb.rb:244:in `block in from_file'

    ruby_block("config_replicaset") do
      params {:mongodb_type=>"mongod", :action=>[:enable, :start], :logpath=>"/var/log/mongodb/mongod.log", :configservers=>[], :replicaset=>true, :notifies=>[], :not_if=>[], :name=>"mongod"}
      action [:nothing]
      default_guard_interpreter :default
      block_name "config_replicaset"
      declared_type :ruby_block
      cookbook_name "sc-mongodb"
      recipe_name "replicaset"
      block #<Proc:0x00000000056a4ca8@/tmp/chef-zero340752472/local-mode-cache/cache/cookbooks/sc-mongodb/definitions/mongodb.rb:245>
    end

    System Info:
    ------------
    chef_version=13.7.16
    platform=redhat
    platform_version=7.4
    ruby=ruby 2.4.3p205 (2017-12-14 revision 61247) [x86_64-linux]
    program_name=/usr/bin/chef-client
    executable=/opt/chef/bin/chef-client

I searched through the cookbook and was unable to find a place where rs_member_ips variable would be initialized:

$ grep -rn rs_member_ips sc-mongodb/
sc-mongodb/libraries/mongodb.rb:135:      elsif config['_id'] == name && config['members'] == rs_member_ips
sc-mongodb/libraries/mongodb.rb:140:        rs_member_ips.each do |mem_h|

On the other hand, the following piece of code might need correction (at least for MongoDB version 3.6.2 that I'm using):

131       if config && config['members'] == rs_members
132         # config is up-to-date, do nothing
133         Chef::Log.info("Replicaset '#{name}' already configured")
134       elsif config['_id'] == name && config['members'] == rs_member_ips
135         # config is up-to-date, but ips are used instead of hostnames, change config to hostnames
136         Chef::Log.info("Need to convert ips to hostnames for replicaset '#{name}'")
137         old_members = config['members'].map { |m| m['host'] }
138         mapping = {}

The value of config variable in my case is as follows:

[2] pry(Chef::ResourceDefinitionList::MongoDB)> config['members']
=> [{"_id"=>0, "host"=>"db01:27017", "arbiterOnly"=>false, "buildIndexes"=>true, "hidden"=>false, "priority"=>1.0, "tags"=>{}, "slaveDelay"=>0, "votes"=>1},
 {"_id"=>1, "host"=>"db03:27017", "arbiterOnly"=>false, "buildIndexes"=>true, "hidden"=>false, "priority"=>1.0, "tags"=>{}, "slaveDelay"=>0, "votes"=>1},
 {"_id"=>2, "host"=>"db02:27017", "arbiterOnly"=>false, "buildIndexes"=>true, "hidden"=>false, "priority"=>1.0, "tags"=>{}, "slaveDelay"=>0, "votes"=>1}]

But rs_members var will never match, because its structure is much simpler:

[4] pry(Chef::ResourceDefinitionList::MongoDB)> rs_members
=> [{"host"=>"db01:27017", "_id"=>0}, {"host"=>"db03:27017", "_id"=>1}, {"host"=>"db02:27017", "_id"=>2}]

At the same time, the comparison in else branch will also fail as config['members'] will also hardly match the hash that rs_member_ips would have contained had it been initialized.

mike-stewart commented 6 years ago

I'm getting this same problem on the latest version of the cookbook (1.0.1). Seems to have been introduced by #166: https://github.com/sous-chefs/mongodb/pull/166/files#diff-99705ecfdc27db6ed855d20d15ca9d2bL83

mike-stewart commented 6 years ago

Actually, this is a duplicate of #179.

UncleIS commented 6 years ago

Agree that this is a duplicate and can be closed unless there are details that might be useful for #179

lock[bot] commented 5 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.