poise / poise-derived

A Chef cookbook for defining lazily evaluated node attributes.
Apache License 2.0
22 stars 5 forks source link

chef-shell in client mode does not work #3

Open smt116 opened 7 years ago

smt116 commented 7 years ago

Background

We are using poise-derived cookbook for lazy attributes. It works fine in our ecosystem.

Problem

The problem was when we had to use the chef-shell command in a client mode to make some debugging.

It does not work and it raises the following error:

 $ chef-shell -z -l debug

[...]

[2017-01-02T15:13:45+00:00] DEBUG: [poise-derived] Installing event handler
[2017-01-02T15:13:45+00:00] DEBUG: Filtered backtrace of compile error: /var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/handler.rb:41:in `<class:Handler>',/var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/handler.rb:28:in `<module:PoiseDerived>',/var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/handler.rb:23:in `<top (required)>',/var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/cheftie.rb:18:in `<top (required)>',/var/chef/cache/cookbooks/poise-derived/libraries/default.rb:19:in `<top (required)>'
[2017-01-02T15:13:45+00:00] DEBUG: Backtrace entry for compile error: '/var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/handler.rb:41:in `<class:Handler>''
[2017-01-02T15:13:45+00:00] DEBUG: Line number of compile error: '41'

================================================================================
Recipe Compile Error in /var/chef/cache/cookbooks/poise-derived/libraries/default.rb
================================================================================

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

Cookbook Trace:
---------------
  /var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/handler.rb:41:in `<class:Handler>'
  /var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/handler.rb:28:in `<module:PoiseDerived>'
  /var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/handler.rb:23:in `<top (required)>'
  /var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/cheftie.rb:18:in `<top (required)>'
  /var/chef/cache/cookbooks/poise-derived/libraries/default.rb:19:in `<top (required)>'

Relevant File Content:
----------------------
/var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/handler.rb:

 34:
 35:      def attribute_load_complete
 36:        PoiseDerived::DSL.uninstall
 37:      end
 38:
 39:      # Install event handler.
 40:      Chef::Log.debug('[poise-derived] Installing event handler')
 41>>     Chef.run_context.events.register(self.instance)
 42:    end
 43:  end
 44:

Platform:
---------
x86_64-linux

epic fail!

/var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/handler.rb:41:in `<class:Handler>': undefined method `events' for nil:NilClass (NoMethodError)
    from /var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/handler.rb:28:in `<module:PoiseDerived>'
    from /var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/handler.rb:23:in `<top (required)>'
    from /opt/chef/embedded/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /opt/chef/embedded/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /var/chef/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/cheftie.rb:18:in `<top (required)>'
    from /opt/chef/embedded/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /opt/chef/embedded/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /var/chef/cache/cookbooks/poise-derived/libraries/default.rb:19:in `<top (required)>'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/run_context/cookbook_compiler.rb:193:in `load'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/run_context/cookbook_compiler.rb:193:in `block in load_libraries_from_cookbook'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/run_context/cookbook_compiler.rb:189:in `each'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/run_context/cookbook_compiler.rb:189:in `load_libraries_from_cookbook'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/run_context/cookbook_compiler.rb:99:in `block in compile_libraries'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/run_context/cookbook_compiler.rb:98:in `each'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/run_context/cookbook_compiler.rb:98:in `compile_libraries'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/run_context/cookbook_compiler.rb:71:in `compile'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/run_context.rb:187:in `load'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/shell/shell_session.rb:208:in `rebuild_context'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/shell/shell_session.rb:59:in `block in reset!'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/shell/shell_session.rb:101:in `loading'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/shell/shell_session.rb:54:in `reset!'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/shell.rb:127:in `session'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/shell.rb:136:in `init'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/lib/chef/shell.rb:65:in `start'
    from /opt/chef/embedded/lib/ruby/gems/2.3.0/gems/chef-12.17.44/bin/chef-shell:34:in `<top (required)>'
    from /usr/bin/chef-shell:57:in `load'
    from /usr/bin/chef-shell:57:in `<main>'

It looks like a bug in the handler definition. Chef.run_context is nil in that mode while in the normal chef-client it is a Chef::RunContext object.

Software versions

Chef: 12.17.44

smt116 commented 7 years ago

@coderanger ping.

kalebwalton commented 7 years ago

I wonder if some derivation of http://gsandie-blog.logdown.com/posts/168475-chef-11-libraries-and-lwrp-testing-in-chef-shell could work to resolve this.

Snippet from the above URL:

Chef::Config[:cookbook_path] = "/path/to/your/cookbooks"
run_list = "recipe[partial_search]"
cl = Chef::CookbookLoader.new(Chef::Config[:cookbook_path])
cl.load_cookbooks
cookbook_collection = Chef::CookbookCollection.new(cl)
@events = Chef::EventDispatch::Dispatcher.new()
node.run_context = Chef::RunContext.new(node, cookbook_collection, @events)
node.run_list = Chef::RunList.new(run_list)
node.run_context.load(node.expand!)
kalebwalton commented 7 years ago

This does it. I'm not too experienced with this level of Chef'ing... so I'm sure this could be more concise.

    # Install event handler.
    Chef::Log.debug('[poise-derived] Installing event handler')
    if Chef.run_context.nil?
      cl = Chef::CookbookLoader.new(Chef::Config[:cookbook_path])
      cl.load_cookbooks
      cookbook_collection = Chef::CookbookCollection.new(cl)
      @events = Chef::EventDispatch::Dispatcher.new()
      Chef.node.run_context = Chef::RunContext.new(Chef.node, cookbook_collection, @events)
      Chef.node.run_context.load(Chef.node.expand!)
      Chef.set_run_context Chef.node.run_context
    end
    Chef.run_context.events.register(self.instance)
coderanger commented 7 years ago

I don't use chef-shell personally so if someone wants to submit a patch for this I can take a look. Overall not much interest from me in supporting chef-shell since I don't think it's a useful tool.

The above patch is probably not what is needed, the issue is that chef-shell doesn't have a converge lifecycle in the way chef-client/solo do, so there is nothing to hook in to to set up the DSL methods. Without that, the cookbook attributes files would just fail to load.