diff --git a/rattail_fabric/python.py b/rattail_fabric/python.py index a6c33f5..72aa0cb 100644 --- a/rattail_fabric/python.py +++ b/rattail_fabric/python.py @@ -26,6 +26,7 @@ Fabric Library for Python from __future__ import unicode_literals, absolute_import +import os from contextlib import contextmanager import six @@ -67,14 +68,21 @@ def pip(*packages, **kwargs): else: upgrade_strategy = '' use_sudo = kwargs.pop('use_sudo', True) + runas_user = kwargs.pop('runas_user', None) if kwargs: abort("Unknown kwargs for pip(): {}".format(kwargs)) packages = ["'{}'".format(p) for p in packages] - run_ = sudo if use_sudo else run - run_('pip install {} {} {}'.format(upgrade, upgrade_strategy, ' '.join(packages))) + cmd = 'pip install {} {} {}'.format(upgrade, upgrade_strategy, ' '.join(packages)) + if use_sudo: + kw = {} + if runas_user: + kw['user'] = runas_user + sudo(cmd, **kw) + else: + run(cmd) -def install_virtualenvwrapper(workon_home=None, user='root', use_apt=False): +def install_virtualenvwrapper(workon_home=None, user='root', use_apt=False, configure_me=True): """ Install the `virtualenvwrapper`_ system, with the given ``workon`` home, owned by the given user. @@ -85,10 +93,9 @@ def install_virtualenvwrapper(workon_home=None, user='root', use_apt=False): apt.install('virtualenvwrapper') else: pip('virtualenvwrapper', upgrade=True) - configure_virtualenvwrapper('root', workon_home) - if user != 'root': - configure_virtualenvwrapper(user, workon_home) - configure_virtualenvwrapper(env.user, workon_home) + configure_virtualenvwrapper(user, workon_home) + if configure_me: + configure_virtualenvwrapper(env.user, workon_home) def configure_virtualenvwrapper(user, workon_home=None, wrapper='/usr/local/bin/virtualenvwrapper.sh'): @@ -96,7 +103,7 @@ def configure_virtualenvwrapper(user, workon_home=None, wrapper='/usr/local/bin/ Configure virtualenvwrapper for the given user account. """ workon_home = workon_home or getattr(env, 'python_workon_home', '/srv/envs') - home = sudo('echo $HOME', user=user) + home = sudo('getent passwd {} | cut -d: -f6'.format(user)) home = home.rstrip('/') def update(script): @@ -109,16 +116,23 @@ def configure_virtualenvwrapper(user, workon_home=None, wrapper='/usr/local/bin/ update('.profile') update('.bashrc') + sudo('whoami', user=user) # no-op to trigger first hooks -def mkvirtualenv(name, python=None, use_sudo=True, user=None, workon_home=None, +def mkvirtualenv(name, python=None, use_sudo=True, user=None, runas_user=None, workon_home=None, upgrade_pip=True, upgrade_six=True, upgrade_setuptools=True, upgrade_strategy=None): """ Make a new Python virtual environment. """ workon_home = workon_home or getattr(env, 'python_workon_home', '/srv/envs') - run_ = sudo if use_sudo else run - run_('mkvirtualenv {} {}'.format('--python={}'.format(python) if python else '', name)) + cmd = 'mkvirtualenv {} {}'.format('--python={}'.format(python) if python else '', name) + if use_sudo: + kw = {} + if runas_user: + kw = {'user': runas_user} + sudo(cmd, **kw) + else: + run(cmd) if upgrade_pip: if isinstance(upgrade_pip, six.string_types): pip_req = upgrade_pip @@ -126,15 +140,17 @@ def mkvirtualenv(name, python=None, use_sudo=True, user=None, workon_home=None, pip_req = 'pip' with workon(name): if upgrade_six: - pip('six', upgrade=True, use_sudo=use_sudo) - pip(pip_req, upgrade=True, use_sudo=use_sudo) + pip('six', upgrade=True, use_sudo=use_sudo, runas_user=runas_user) + pip(pip_req, upgrade=True, use_sudo=use_sudo, runas_user=runas_user) if upgrade_setuptools: pip('setuptools', 'wheel', 'ndg-httpsclient', upgrade=True, upgrade_strategy=upgrade_strategy, - use_sudo=use_sudo) + use_sudo=use_sudo, runas_user=runas_user) if user: - with cdvirtualenv(name, workon_home=workon_home): + with cd(os.path.join(workon_home, name)): mkdir('app/log', owner='{0}:{0}'.format(user)) + if use_sudo and runas_user: + sudo('chown {}: /srv/envs/{}/app'.format(runas_user, name)) @contextmanager