Greetings, oh wizards of puppet internals. (and other titles and
salutations as appropriate)
I've been doing some work lately on the `pip` package provider and,
despite some assistance on my PR
(
https://github.com/puppetlabs/puppet/pull/2170) and IRC, I think I've
hit a brick wall.
( Aside, For those not familiar with Python pip/virtualenv: pip is
Python's next-gen package management tool. It can work either
system-wide (installing packages under /usr/lib/python or some such
path), or by operating on packages in python virtual environments, which
are totally* isolated python environments rooted at a specific,
arbitrary directory, containing their own copy of the python interpreter
and other binaries, their own libraries/modules/packages, etc. *To
complicate things a bit, a virtualenv can optionally include system-wide
packages. I'm not sure if there's an exact parallel in other languages -
I assume it's roughly analogous to a combination of bundler and
rvm/rbenv, if they were builtin parts of ruby. )
My plan was to add virtualenv (aka virtual environment / venv) support
to the `pip` provider (this is, IMO, the most common use case of pip
these days). I got to a somewhat-working point by adding a "prefix"
parameter to the package type and, if specified, having the pip provider
call #{prefix}/bin/pip instead of the system-wide pip, which has the
effect of operating only on the virtualenv rooted at #{prefix}.
I got to the point that I thought I had working code (that's PR 2170
linked above, now closed) when I hit a few major bumps in the road. Or,
the road disappeared.
1) The provider prefetches. As such, if a package "foo" is installed
system-wide (i.e. under /usr/lib/python2.x/site-packages) it's seen as
installed and never passed on to the provider, so my pip-path-munging to
install in a virtualenv is never called.
2) In the case where the package isn't already present system-wide, and
execution does make it to the provider, my patch will manage it fine,
but the package can still only be managed in one virtualenv on a given
system. A composite namevar seems to be the only way to handle this, but
that doesn't seem possible for a single provider, just for a type.
Given all this, and the pending discussion about tiering providers, can
anyone provide some advice on whether it's even worth pursuing this path
vs developing a python/virtualenv module to publish on the forge,
presumably which would contain an awfully-named type (pippackage)? Or,
if the former, is there something I'm missing about how types and
providers work (and the package type specifically) that would make this
easier? I work with one of the pip/virtualenv maintainers, and there's a
strong desire to have a canonical way to manage them in Puppet, whether
it be in core or a module.
Thanks in advance for any advice, guidance, or explanations of my
insanity. This is my first real attempt at type/provider development (or
ruby, for that matter).
-Jason Antman