Rubygems in Puppet modules, revisited

22 views
Skip to first unread message

R. Tyler Croy

unread,
Apr 28, 2014, 11:45:20 AM4/28/14
to puppe...@googlegroups.com
In my previous thread "Can I make my entire module "depend" on rubygems being
installed?" I think I mischaracterized the problem.


Basically, I would like to use a Ruby gem inside of a Puppet module which
contains a custom provider. There's an inherent problem in this appraoch, for
example:

class {
'jenkins' :
require => Package[mygem];
}

This iwll require *two* Puppet runs to operate correctly, one to install the
gem properly, and the second to load the gem properly into the Puppet runtime
environment.

The best solution I have to prevent this 2-run problem is to vendor my ruby gem
into the Puppet module and hope that I can keep track of upstream properly for
necessary bug fixes and security patches :(


Is there no better way to depend on shared Ruby code for my module? Does the
Modulefile allow for declaring a dependency like this to be installed at
`puppet module install` time?



Cheers
- R. Tyler Croy

------------------------------------------------------
Code: <https://github.com/rtyler>
Chatter: <https://twitter.com/agentdero>

% gpg --keyserver keys.gnupg.net --recv-key 3F51E16F
------------------------------------------------------

Felix Frank

unread,
Apr 28, 2014, 11:50:53 AM4/28/14
to puppe...@googlegroups.com
On 04/28/2014 05:45 PM, R. Tyler Croy wrote:
> class {
> 'jenkins' :
> require => Package[mygem];
> }
>
> This iwll require *two* Puppet runs to operate correctly, one to install the
> gem properly, and the second to load the gem properly into the Puppet runtime
> environment.
>
> The best solution I have to prevent this 2-run problem is to vendor my ruby gem
> into the Puppet module and hope that I can keep track of upstream properly for
> necessary bug fixes and security patches :(

I vaguely remember talk of providers coming available during the agent
run. Perhaps this is what you're looking for here. If so, it would
probably Just Work.

> Is there no better way to depend on shared Ruby code for my module? Does the
> Modulefile allow for declaring a dependency like this to be installed at
> `puppet module install` time?

I believe this question is not valid. The gem is required agent side,
yes? puppet module install will operate master side, where gem support
should be of no relevance.

Regards,
Felix

Dominic Cleal

unread,
Apr 28, 2014, 12:00:27 PM4/28/14
to puppe...@googlegroups.com
On 28/04/14 16:45, R. Tyler Croy wrote:
> In my previous thread "Can I make my entire module "depend" on
> rubygems being installed?" I think I mischaracterized the problem.
>
>
> Basically, I would like to use a Ruby gem inside of a Puppet module
> which contains a custom provider. There's an inherent problem in
> this appraoch, for example:
>
> class { 'jenkins' : require => Package[mygem]; }
>
> This iwll require *two* Puppet runs to operate correctly, one to
> install the gem properly, and the second to load the gem properly
> into the Puppet runtime environment.

This is possible using "features" (that is, system features, not
provider features). You first write a feature definition that says
you expect library X to become available. You then confine your
provider to depend that feature being available, the Puppet will delay
evaluation of those resources until the feature becomes available in
the same way it does with commands. This has been available since
2.7.20 (ticket #14822).

Here's an example of a feature:
https://github.com/theforeman/puppet-foreman/blob/master/lib/puppet/feature/foreman_api.rb.
The "libs" argument has to be the name of the library passed to require.

The confine looks like this:
https://github.com/theforeman/puppet-foreman/blob/master/lib/puppet/provider/foreman_smartproxy/rest.rb#L3

However there's a gotcha if you're requiring gems, as we have to flush
the load paths or they get cached with the currently loaded set of
gems. This has only just been fixed for Puppet 3.6.0:
https://tickets.puppetlabs.com/browse/PUP-1879

I can't really think of a workaround for this issue either, unless you
can figure out how to run some arbitrary code after each resource is
evaluated to clear cached paths.

--
Dominic Cleal
Red Hat Engineering
Reply all
Reply to author
Forward
0 new messages