On Mon, Feb 9, 2015 at 4:23 PM, Trevor Vaughan <tvaug...@onyxpoint.com>
wrote:

> I was talking with a few folks today about potential resolutions to module
> namespace issues.
>
> == Fundamental Issue ==
>
> puppetlabs_apache -- Installs To --> apache
> example42_apache -- Installs To --> apache
> theforeman_apache -- Installs To --> apache
>
> You get my point...
>
> ...

> == The First Proposal ==
>
> Inspired by RVM Gemsets, how about allowing modules to declare which
> version of a given module they will use?
>
> /etc/puppet/modules/apache/puppetlabs/{files,modules,manifests}
> /etc/puppet/modules/apache/theforeman/{files,modules,manifests}
> /etc/puppet/modules/apache/<author>/{files,modules,manifests}
>
> Then, use could be dictated by something like: include apache@puppetlabs.
>
> Unfortunately, this really comes down to the parser being able to
> understand the following:
>
> include apache => See if there are any @'s and use that one
> include apache@puppetlabs => include the Puppetlabs apache
> include apache@puppetlabs && include apache@theforeman => Fail, conflict
>
> == Alternative ==
>
> One possible alternative is to just use the metadata.json file to dictate
> which module will be used when loading other modules.
>
> Again, if there is a conflict, that is a failure but *only* if the code
> attempts to use both at the same time.
>
> The benefit here is that it should make things very unambiguous while the
> drawback (if it really is) is that you *must* put a metadata.json file in
> every module that you create.
>
> This is just a set of thoughts that I hope get us moving in a direction
> where this type of thing is possible and I look forward to hearing what
> people think (good, bad, or ugly)!
>

== Alternative #2: Namespaced Module-Sets ==

Let's call it "Namespaced Module-Sets"; it's similar to the first proposal
but kinda turned on its end. The concept of the module path is extended
with optional names for any element in the module path. These names can
then be used as a namespace prefix to address classes within a particular
module-set. From within the module-set, references to classes do not need
to be qualified (or perhaps, within a named set must not be) and these
references are local-first, meaning that the set is searched before the
module path is searched.

With this scheme, 3rd party module authors do not need to change the
dependencies of their modules nor the names by which they refer to these
dependencies. Local devadmins have the ability to use multiple modules that
present internally the same top-level namespace and to mix in modules that
are dependent on specific versions of those.

Example: I'll use YAML to represent the namespaced module path, but I'm not
necessarily presenting this as the way it would actually be configured.

---
modulepath:
  # Our local modules, without an attached name
  - path: /etc/puppet/modules/local
  # PuppetLabs modules and modules that depend on them
  - path: /etc/puppet/modules/puppetlabs
    name: puppetlabs

One could have a node defined to use our local "apache" module and another
node defined to use "puppetlabs::apache", which is installed in
/etc/puppet/modules/puppetlabs. Now one could also use puppetlabs/passenger
by installing it to /etc/puppet/modules/puppetlabs. Because scope
references are local-first, passenger/manifests/init.pp's "include
'::apache'" refers to "::puppetlabs::apache".

The biggest problem I see with this scheme is with Ruby components that are
not Puppet-namespaced. Within a module-set there would be no problem, as
the local-first would still apply, but if, e.g., functions with the same
name were in different module-sets, then the language would need to be
extended to support namespaces in these.

And there are a number of other details that would need to be worked out,
including but not limited to:
  * Hiera lookups; I have a feeling that there is some complexity here that
is escaping me
  * Would it fall back to looking in named module-sets for unqualified
names? If there were an unnamed module-set after a named module-set, which
would be searched first?
  * My feeling is that the use of named module-sets and the names chosen
for them should be a local-only decision. That is, distributed modules
should never assume anything about the existence of module-set names,
either by convention or technical restriction. (So, for example, one would
only expect to use them within a role or profile or node definition.) There
are probably gray areas with this that I am not seeing.
  * A variation would be to not allow unnamed module-sets at the local
level, but this would be a breaking change, whereas the above should be
backwards compatible.
  * Additional complexity for r10k/pmt/etc. probably?

In some ways, this is a lot like environments, but unlike environments,
which are unique at the node-level, these allow the use of multiple
module-sets and are scoping for entities at the manifest-level. As I
understand environments, they can (and probably usually should) be
relatively isolated from each other; the purpose of namespaced module-sets
is to allow addressing without isolation. Maybe this is what Henrik's last
message in this thread is getting at when he says:

I have claimed on many occasions that an environment is just like a module
> (with higher privileges / precedence). The set of available modules should
> be more of a repository kind of thing that the loader resolves modules from.


Wil

-- 
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/CAMmm3r7X%3DfV5TcsbAZ07QHuE7Qt%3DjeEJN1anDK_GsN2Zwd6PaQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to