jaraco.deploy / jaraco / deploy /

Support for building Python environments on Ubuntu 10.04 servers in
isolated environments.
from fabric.api import run, cd, sudo
from fabric.contrib import files
from fabric.context_managers import hide, settings

import packaging

def install_prerequisites():
	status = sudo('aptitude build-dep -y python2.6')
	packages = packaging.parse_new_packages(status)
	return packages

def _needs_prerequisites():
	status = run('aptitude -s build-dep -y python2.6')
	packages = packaging.parse_new_packages(status)
	return bool(packages)

def _get_home():
	return run('echo ~').splitlines()[-1]

def install_python(versions='2.7.1,2.6.6,2.5.5'):
	Install the specified python versions (comma-separated) to the
	user's home directory. Requires sudo if any prerequisites are not
	already installed.
	root = _get_home()
	installed = install_prerequisites() if _needs_prerequisites() else []
		# install the first version as primary and the subsequent versions
		#  as alternate.
		for ver in versions.split(','):
			install_python_version(root, ver, alt)
		# we don't need these any more
def install_python_version(root, ver, alt=False):
	Install a given version of Python from source to the specified
	root (aka prefix).
	If `alt` is indicated, Python will be installed as alternate (i.e.
	no `python` executable).
	longver = 'Python-%(ver)s' % vars()
	if not files.exists(longver):
		run('wget{ver}/{longver}.tgz -O - | tar xz'.format(**vars()))
	with cd(longver):
		run('./configure --prefix {root}'.format(**vars()))
		type = 'altinstall' if alt else 'install'
		run('make {type}'.format(**vars()))
	run('rm -R {longver}'.format(**vars()))

def remove_prerequisites(which=None):
	if which is None:
		# these are the packages installed for build-dep python26 on
		#  a "clean" ubuntu 10.04 box.
		which = ('autoconf debhelper blt-dev gdb libbluetooth-dev '
			'libdb4.8-dev libffi-dev libncursesw5-dev libreadline-dev '
			'libsqlite3-dev libssl-dev sharutils tk8.5-dev zlib1g-dev')
		which = ' '.join(which)
	if not which:
	sudo('aptitude remove -y ' + which)

def install_setuptools(pyvers = '2.5,2.6,2.7'):
	Install setuptools 0.6c11 for the various versions of Python. The
	last version installed will be default for commands such as
	for pyver in pyvers.split(','):
		eggname = 'setuptools-0.6c11-py{pyver}.egg'.format(**vars())
		run('sh {eggname}'.format(**vars()))
		run('rm {eggname}'.format(**vars()))

def install_distribute():
	run('wget -O - | python')
	run('rm distribute-0.6.*.tar.gz')

def install_virtualenv():
	"Install virtualenv to the default setuptools-enabled Python"
	run('easy_install virtualenv')

def cleanup():
	"clean up the build Python environments"
	run('rm -R bin include lib share')

def remove_singly_installed_package(package_expr):
	Remove package from easy_install.pth
	This is particularly useful when you run into infinite loops when
	attempting to eggmonster to upgrade a package that's
	Be careful that package_expr matches exactly the package you're
	seeking to remove. (such as pear-2.1-py)
	easy_install_pth = run(
		'''python -c "import os, distutils.sysconfig; print(os.path.join(distutils.sysconfig.get_python_lib(), 'easy-install.pth'))"''')
	cmd = "grep '{package_expr}' " + easy_install_pth
	cmd = cmd.format(**vars())
	print cmd
	cmd = "sed -i '/{package_expr}/d' " + easy_install_pth
	cmd = cmd.format(**vars())