I'm working on a module to handle creating and populating Python
virtualenvs. Without going into too much detail, basically these are
nicely-encapsulated environments into which python packages can be
installed and run. It's not uncommon to have several virtualenvs on a
system, potentially with the same packages installed (maybe different
versions).
Puppet's defines are here to help with stuff that can be installed
multiple times on a particular system, but this particular situation is
two-layered: I want to install the same version of Twisted into two
different virtualenvs.
Here's the code:
define python::virtualenv($python, $ensure="present", $packages) {
include python::package_dir
$virtualenv = $title
case $ensure {
present: {
file {
# create the virtualenv directory
"$virtualenv":
ensure => directory;
}
$touchfile = "$virtualenv/.ve-setup"
exec {
"virtualenv $virtualenv":
logoutput => on_failure,
name => "$python $package_dir/virtualenv.py \
--python=$python --distribute $virtualenv \
&& touch '$touchfile'",
require => [
File[$package_dir],
],
creates => $touchfile;
}
python::package {
$packages:
virtualenv => $virtualenv;
}
}
absent: {
# absent? that's easy - blow away the directory
file {
"$virtualenv":
ensure => absent,
backup => false,
force => true;
}
}
}
}
class python::package_dir {
file {
"$package_dir":
source => "puppet:///python/package_dir",
recurse => true,
purge => true,
backup => false;
}
}
define python::package($virtualenv) {
include python::package_dir
$pkg = $title
# the tarball to install from
$tarball = "$package_dir/$pkg.tar.gz"
# pip options to make sure no internet access occurs
$pip_options = "--upgrade --no-deps --no-index --find-links/nosuchdir"
exec {
"virtualenv-package-$virtualenv-$pkg":
logoutput => on_failure,
name => "$virtualenv/bin/pip install $pip_options $tarball",
unless => "/usr/bin/test -d
'$virtualenv/lib/python'*'/site-packages/$pkg'*'.egg-info'",
require => [ File[$package_dir], Exec["virtualenv
$virtualenv"] ];
}
}
# site.pp:
import "python"
node default {
python::virtualenv {
"/tools/virtualenv-1":
python => "/usr/bin/python",
packages => [ 'mock-0.6.0' ];
"/tools/virtualenv-2":
python => "/usr/bin/python2.4",
packages => [ 'mock-0.6.0' ];
}
}
The trained eye can probably see immediately why this doesn't work - it
tries to instantiate two copies of Python::Package[mock-0.6.0], each
with different $virtualenv parameters.
I think I could make this particular process work if I could qualify the
Python::Package resource names, and then un-qualify them to figure out
what package to install and what virtualenv to install it in. Then I
would have
Python::Package[/tools/virtualenv-1|mock-0.6.0]
Python::Package[/tools/virtualenv-2|mock-0.6.0]
In the python::package define, I could split $title into $virtualenv and
$pkg easily enough with regsubst(). However, how can I take an array of
bare package names and prepend the virtualenv name and "|" to each one?
Another thought is that I could use Exec directly, since it is not
impeded by duplicate resource names. That would mean replacing the
python::package resource instantiation with something like
exec {
$packages:
name => "$virtualenv/bin/pip install $title";
}
but the $title there won't be qualified with each element of the
$packages array -- it will be the value of $title from the enclosing
scope (define python::virtualenv)
So, is there a better way to approach this problem? I'm worried that if
I can't get something this simple figured out, I'm not going to be able
to get Puppet to do the more complex things I'd like..
Dustin
--
You received this message because you are subscribed to the Google Groups
"Puppet Users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/puppet-users?hl=en.