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 puppet-users@googlegroups.com.
To unsubscribe from this group, send email to
puppet-users+unsubscribe@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/puppet-users?hl=en.