Issue #12173 has been updated by Jeff McCune.

<blockquote>
Are you sure about that? As the old saw goes, “any problem in computer science 
can be solved with enough layers of indirection.” It seems to me that this 
issue could be addressed by interposing per-environment classes or (Ruby) 
modules into which native plugins are loaded, and from which they are resolved 
/ used. Perhaps implementing such a thing would require touching a lot of code, 
but given the amount of metacode in Puppet, I don’t think that’s a given.
</blockquote>

Unfortunately we're fairly confident process-per-environment is the least-poor 
way to proceed.  We'd prefer to solve this using interposing per-environment 
classes or some other form of containment.  I haven't been able to find a 
suitable container in MRI though.  Java has a sophisticated class loader which 
would be an effective tool in this problem area.  Ruby lacks this level of 
sophistication with regard to class loading.  Anonymous classes are possible in 
Ruby, but a way to keep track of these anonymous classes needs to be built and 
maintained.  Furthermore, anonymous classes have an annoying property.  When an 
anonymous class is assigned to a constant, the class assumes the identity of 
the constant.  This seems intuitive, but Puppet refers to classes using 
constants all over the place, like Puppet::Type::File:

<pre>
irb(main):005:0> Puppet::Type.type :file
=> Puppet::Type::File
</pre>

Even if a sophisticated anonymous class manager lived behind the `type` class 
method, all of the other anonymous :file classes would be inaccessible as soon 
as one of them is bound to Puppet::Type::File.  We'd have to re-assign the 
constant over and over, which is difficult because constants are not thread 
safe.  At this point we'd have to build and manage a fairly sophisticated lock 
manager and we've made the entire system inherently thread un-safe.

This leaves us with eliminating every place where a type or provider (or any 
extension for that matter) class is assigned to a constant.  That's a pretty 
massive undertaking, especially considering the relative lack of Ruby 
refactoring tools and the heavy use of meta-programming inside the Puppet RAL.

Which leaves us with the process itself as the next level of abstraction...  Or 
switching to another runtime environment for the master, like the JVM, but even 
then we'd need to have different jruby heaps so the efficiency benefit is 
unclear.
In any case, surely it would be better to find a way to make the feature work 
as it was always promised to do, instead of pulling back with an “oops, no can 
do.”

I've been wracking my brain for years on this one...  and I'm out of fresh 
ideas.  Do you see anything I'm overlooking with the way MRI behaves?  We're 
moving to 1.9.3 now, so perhaps there's some new behavior I'm unaware of 
compared to 1.8.7 and earlier versions.

----------------------------------------
Bug #12173: Masters cannot reliably distinguish between multiple versions of a 
type/function/plugin used in different environments
https://projects.puppetlabs.com/issues/12173#change-90785

* Author: Nigel Kersten
* Status: Accepted
* Priority: Normal
* Assignee: eric sorenson
* Category: environments
* Target version: 3.x
* Affected Puppet version: 2.7.0
* Keywords: telly_deprecation BD
* Branch: 
----------------------------------------
Quoted from a previous ticket, #4409

The key problem is that a master can’t reliably distinguish between two 
versions of the same native type that are used in different environments (or 
between an environment which uses a native type and an environment which 
doesn’t). This is due to the fact that native types are defined using ruby 
code, which the master loads into Ruby classes via “require”. Since there can 
only be one Ruby class with a given name at a time, this prevents the master 
from being able to have two different versions of the same type in two 
different environments. This makes life difficult for people who are trying to 
use a “test” environment to try out a new version of a native type on a limited 
set of nodes before deploying it to all nodes.

A secondary problem is that the location where the master looks for the 
definition of native types is not the same as the location of plug-in files 
that the master distributes to agents. This leads to confusion even for people 
who are not using a “test” environment, because it means that they have to put 
their type definitions in two places, one where they can be picked up by the 
master and one where they can be sent as plug-ins to agents.


-- 
You have received this notification because you have either subscribed to it, 
or are involved in it.
To change your notification preferences, please click here: 
http://projects.puppetlabs.com/my/account

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Bugs" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/puppet-bugs?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to