On Mon, Dec 1, 2014 at 11:44 AM, Trevor Vaughan <tvaug...@onyxpoint.com>
wrote:

> Well that makes a ridiculous amount of sense.
>
> Thanks for posting, I'll check it out tomorrow.
>
> Trevor
>
> On Mon, Dec 1, 2014 at 4:20 AM, Gavin Williams <fatmc...@gmail.com> wrote:
>
>> The code I've added to work-around the Puppet issue is here[1].
>>
>
>> HTH.
>>
>> Gav
>>
>> [1]https://gist.github.com/fatmcgav/aa7295798502d660c6a3
>>
>
Thanks Gavin for posting that, and for the ticket and PR. I think your
"work-around" is really the right thing to be doing.

Puppet's autoloader has a fatal flaw that causes a host of issues where
code cannot be loaded. See the linked issues in
https://projects.puppetlabs.com/issues/7316

A good example is the case where you have a module defining a new type in
lib/puppet/type/foo.rb:

  require 'puppet/type/bar'

  Puppet::Type.newtype(:foo) do
  end

And the `foo` type requires helper code `bar` from within the same (or
different) module. The problem with puppet's autoloader is that it only
participates in the loading of `foo`, but is "out of the loop" when `foo`
requires `bar`. As a result we have the autoloader loading `foo`, but Ruby
loading `bar`. What could possibly go wrong?

1. Well, the autoloader searches the current environment's modulepath to
load `foo`, but Ruby only knows about $LOAD_PATH. As a result, modules
often fail to load their helper code[1], or the module works around it by
using the absolute path to the helper code[2], or it tries to rescue
LoadError and do something "smart"[3]. This is a terrible pattern.

2. The autoloader uses `Kernel.load` to load `foo`[4], but Ruby requires
`bar`. If the class has already been required, the former will reload the
class, whereas the latter will not. In long running processes, e.g. master,
it is possible for the autoloader to reload a new version of a function,
but never reload the helper code that the function relies on[5]. So you
have a new version of `foo` running with an old version of `bar`, leading
to nearly impossible to debug scenarios, e.g. NoMethodErrors that magically
disappear when you restart the master[6].

3. Historically, the Puppet[:libdir] setting has allowed multiple
directories to be added to the autoloader's search path, but it has no
effect on Ruby's $LOAD_PATH. While this "works" in some cases, e.g when
using puppet as a library or rspec tests[7], it would fail hard if you ever
tried to run `puppet apply` with that setting[8].

4. To solve https://projects.puppetlabs.com/issues/7316, Andy and I took
the approach that puppet (the application) should be responsible for
setting up the ruby $LOAD_PATH[9], and puppet (the library) should just use
the current $LOAD_PATH.

I think we should do something similar for the rspec-puppet case, where the
thing that runs the tests is responsible for updating the $LOAD_PATH to
include module specific paths. But this raises a few questions:

Does this belong in rspec-puppet, puppetlabs_spec_helper, or puppet's own
testing methods (lib/puppet/test/helper.rb)?

What environment/modulepath should be used, especially once legacy
environment support is removed[10]?

Josh

[1] https://tickets.puppetlabs.com/browse/PUP-3336
[2]
https://github.com/puppetlabs/puppetlabs-mysql/blob/master/lib/puppet/provider/mysql_database/mysql.rb#L1
[3]
https://github.com/puppetlabs/puppetlabs-registry/blob/master/lib/puppet/provider/registry_key/registry.rb#L2-L12
[4]
https://github.com/puppetlabs/puppet/blob/3.7.3/lib/puppet/util/autoload.rb#L62
[5] https://tickets.puppetlabs.com/browse/PUP-1033
[6] https://tickets.puppetlabs.com/browse/PUP-2380
[7]
https://github.com/rodjek/rspec-puppet/blob/master/lib/rspec-puppet/support.rb#L140
[8]
https://tickets.puppetlabs.com/browse/PUP-3336?focusedCommentId=114681&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-114681
[9]
https://github.com/puppetlabs/puppet/blob/3.7.3/lib/puppet/util/command_line.rb#L135-L141
[10] https://tickets.puppetlabs.com/browse/PUP-3268

-- 
Josh Cooper
Developer, Puppet Labs

*Join us at **PuppetConf 2015, October 5-9 in Portland, OR - *
http://2015.puppetconf.com.
*Register early to save 40%!*

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-dev/CA%2Bu97u%3DaUST95KmRF-E4wx43q3wMfsK8SNvXTEY4U9aHsYe_EA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to