This issue tracker is now in read-only archive mode and automatic ticket export has been disabled. Redmine users will need to create a new JIRA account to file tickets using https://tickets.puppetlabs.com. See the following page for information on filing tickets with JIRA:

We've Moved!

Because we do not add all module lib directories to Ruby’s search path, ruby classes that exist only in the modules (because they have not yet been synced via pluginsync) cannot be found. The autoloader correctly loads files from the modules, but ruby itself can’t load supporting classes.

Old description:

At present we can copy parser functions, types and providers out with plugins sync, this works fine.

It seems though we cannot copy out Puppet::Util::* classes – useful for code accessed by various parser functions for example.

I need to do something like:

require File.dirname(__FILE__) + '/../../util/foo.rb'

from a parser function since:

require 'puppet/util/foo'

doesnt work.

I am also keen to be able to copy out new application classes that will tie into the puppet single executable thing, i guess these 2 features might be in the same realm.

I think this is related to another ticket, but I can’t find the ticket – basically, not all of the module ‘lib’ directories are added to Ruby’s search path. I thought Dan opened this ticket, but I couldn’t find it.

Loading a “library” plugin that’s used by multiple puppet functions. If it’s sync’d down to /var/lib/puppet/lib/puppet/util/foo.rb then a function with ‘require “puppet/util/foo”’ doesn’t load it as expected. I think most of the comments , $RUBYLIB etc, are addressing this.

Adding additional destinations for things like Puppet::Util::Log. These aren’t require’d by any functions, so need to get autoloaded by the application framework somehow. I only see Puppet::Util::Autoload.new instances for plugins in puppet/type, puppet/provider, puppet/parser/functions, & puppet/feature (?). James mentioned my particular use case in comment # 10 by just evaluating *.rb under the :plugindest directory.

I could have sworn there was also an open ticket something like “plugin paths shouldn’t be added to ruby $RUBYLIB”.

Loading a “library” plugin that’s used by multiple puppet functions. If it’s sync’d down to /var/lib/puppet/lib/puppet/util/foo.rb then a function with ‘require “puppet/util/foo”’ doesn’t load it as expected. I think most of the comments , $RUBYLIB etc, are addressing this.

I agree.

Adding additional destinations for things like Puppet::Util::Log. These aren’t require’d by any functions, so need to get autoloaded by the application framework somehow. I only see Puppet::Util::Autoload.new instances for plugins in puppet/type, puppet/provider, puppet/parser/functions, & puppet/feature (?). James mentioned my particular use case in comment # 10 by just evaluating *.rb under the :plugindest directory.

I’m not sure this has ever been asked for; it would be straightforward to add this as a point of extension. Is there a ticket file to this?

I believe that, as Nigel suggested, that this has been dealt with as part of the autoloader and pluginsync work that Patrick and I did for Telly (#7316, #11858, #12126, etc.).

We do not alter Ruby’s load path to reflect the quirks of our modulepath, but pluginsync will sync module content directly into the agent’s libdir (which is in Ruby’s load path) in a way that should allow the ruby ‘require’ statements to work as expected.

I would love for someone who is a stakeholder for this (R.I., Jeff) to try it out in Telly and let us know if my assessment is incorrect; otherwise I think that we can mark this as fixed in 3.0 and close this ticket.

Recording for posterity, later in the 3.0.0 release we stopped pluginsync on apply, because it clobbers the cache of downloaded plugins from the master with the (almost certainly more limited) set know to the modulepath of ‘puppet apply’. Gem directories (via #7788) and any lib/ subdirectories in modulepath get appended to $: to build up a consistent picture of loadable code without causing agentmaster disparities.

lib/ subdirectories of modules DO NOT get added to $: in the Puppet 3.0.0 release. There was some experimentation with this that hacked the Kernel.require method much like Rubygems does, but that was not put in because of the issue of environments and a threaded environment. At the moment our only threaded environment (that I know of) is in webrick, if we can change webrick to not using threads, then that greatly mitigates some of the problems involved in this.

Bug #9827 shows the exact problem that is caused by not being able to load the library code from modules. The mount_providers module has a file lib/puppet/provider/mountpoint.rb that is loaded with require from lib/puppet/provider/mountpoint/linux.rb. This fails because the mountpoint.rb file is nowhere to be found in the load path.

The mount_providers module has a file lib/puppet/provider/mountpoint.rb that is loaded with require from lib/puppet/provider/mountpoint/linux.rb. This fails because the mountpoint.rb file is nowhere to be found in the load path.

If the autoloader loads module A, and A requires module B, and both modules change, e.g. pluginsync, then the autoloader will never reload B, which will lead to crazy code inconsistency bugs. Fortunately, the agent forks (it will in 3.0.2 #17361) eliminating this issue on the agent side. But it is an issue on the master side, e.g. an autoloaded function requires utility code.

The proposed fix for #7316 will ensure an application can require custom facts, types, providers, applications, faces and actions from the modulepath or gem, and that code can in turn require utility code, also from the modulepath or gem. However, the proposed fix won’t fix this particular issue, for the master to require utility code from a function. Also true for report processors. Additional changes will be required to the compiler to ensure code does not leak across environments, likely fork (but not exec) a child to do the compile.