entorno descargar crear activate activar python virtualenv fabric automated-deploy

python - descargar - Activar un virtualenv vía fabric como usuario de implementación



virtualenv install (8)

Quiero ejecutar mi script de tejido localmente, que a su vez, iniciar sesión en mi servidor, cambiar de usuario para implementar, activar los proyectos .virtualenv, que cambiará dir al proyecto y emitirá un git pull.

def git_pull(): sudo(''su deploy'') # here i need to switch to the virtualenv run(''git pull'')

Normalmente utilizo el comando workon de virtualenvwrapper que origina el archivo de activación y el archivo postactivate me pondrá en la carpeta del proyecto. En este caso, parece que debido a que el tejido se ejecuta desde dentro del caparazón, el control se cede al tejido, por lo que no puedo usar la fuente de bash incorporada en ''$ source ~ / .virtualenv / myvenv / bin / activate''

¿Alguien tiene un ejemplo y una explicación de cómo lo han hecho?


Aquí hay un código para un decorador que dará como resultado el uso del entorno virtual para cualquier llamada run / sudo:

# This is the bash code to update the $PATH as activate does UPDATE_PYTHON_PATH = r''PATH="{}:$PATH"''.format(VIRTUAL_ENV_BIN_DIR) def with_venv(func, *args, **kwargs): "Use Virtual Environment for the command" def wrapped(*args, **kwargs): with prefix(UPDATE_PYTHON_PATH): return func(*args, **kwargs) wrapped.__name__ = func.__name__ wrapped.__doc__ = func.__doc__ return wrapped

y luego para usar el decorador, tenga en cuenta que el orden de los decoradores es importante:

@task @with_venv def which_python(): "Gets which python is being used" run("which python")


Como una actualización del pronóstico de bitprophet: con Fabric 1.0 puede usar prefix() y sus propios administradores de contexto.

from __future__ import with_statement from fabric.api import * from contextlib import contextmanager as _contextmanager env.hosts = [''servername''] env.user = ''deploy'' env.keyfile = [''$HOME/.ssh/deploy_rsa''] env.directory = ''/path/to/virtualenvs/project'' env.activate = ''source /path/to/virtualenvs/project/bin/activate'' @_contextmanager def virtualenv(): with cd(env.directory): with prefix(env.activate): yield def deploy(): with virtualenv(): run(''pip freeze'')


En este momento, puedes hacer lo que hago, que es kludgy pero funciona perfectamente * (este uso asume que estás usando virtualenvwrapper, que deberías serlo), pero puedes sustituirlo fácilmente en la llamada ''fuente'' más larga que mencionaste , si no):

def task(): workon = ''workon myvenv && '' run(workon + ''git pull'') run(workon + ''do other stuff, etc'')

Desde la versión 1.0, Fabric tiene un administrador de contexto de prefix que usa esta técnica para que pueda, por ejemplo:

def task(): with prefix(''workon myvenv''): run(''git pull'') run(''do other stuff, etc'')

* Es probable que command1 && command2 casos en los que el uso del método command1 && command2 pueda explotar, como cuando command1 falla ( command2 nunca se ejecutará) o si command1 no se escapó correctamente y contiene caracteres de shell especiales, y así sucesivamente.


Este es mi enfoque sobre el uso de virtualenv con implementaciones locales.

Utilizando el gestor de contexto path() fabric puede ejecutar pip o python con binarios de virtualenv.

from fabric.api import lcd, local, path project_dir = ''/www/my_project/sms/'' env_bin_dir = project_dir + ''../env/bin/'' def deploy(): with lcd(project_dir): local(''git pull origin'') local(''git checkout -f'') with path(env_bin_dir, behavior=''prepend''): local(''pip freeze'') local(''pip install -r requirements/staging.txt'') local(''./manage.py migrate'') # Django related # Note: previous line is the same as: local(''python manage.py migrate'') # Using next line, you can make sure that python # from virtualenv directory is used: local(''which python'')


Gracias a todas las respuestas publicadas y me gustaría agregar una alternativa más para esto. Hay un módulo, fabric-virtualenv , que puede proporcionar la función como el mismo código:

>>> from fabvenv import virtualenv >>> with virtualenv(''/home/me/venv/''): ... run(''python foo'')

fabric-virtualenv hace uso de fabric.context_managers.prefix , que podría ser una buena manera :)


Si desea instalar los paquetes en el entorno o desea ejecutar comandos de acuerdo con los paquetes que tiene en el entorno, he encontrado este truco para resolver mi problema, en lugar de escribir métodos complejos de estructura o instalar nuevos paquetes de SO:

/path/to/virtualenv/bin/python manage.py migrate/runserver/makemigrations # for running commands under virtualenv local("/home/user/env/bin/python manage.py migrate") # fabric command /path/to/virtualenv/bin/pip install -r requirements.txt # installing/upgrading virtualenv local("/home/user/env/bin/pip install -r requirements.txt") # fabric command

De esta manera es posible que no necesite activar el entorno, pero puede ejecutar comandos en el entorno.


Solo estoy usando una función de envoltura simple virtualenv () a la que se puede llamar en lugar de ejecutar (). No utiliza el administrador de contexto de CD, por lo que se pueden usar rutas relativas.

def virtualenv(command): """ Run a command in the virtualenv. This prefixes the command with the source command. Usage: virtualenv(''pip install django'') """ source = ''source %(project_directory)s/bin/activate && '' % env run(source + command)


virtualenvwrapper puede hacer esto un poco más simple

  1. Usar el enfoque de @ nh2 (este enfoque también funciona cuando se usa local , pero solo para instalaciones virtualenvwrapper donde workon está en $PATH , en otras palabras, Windows)

    from contextlib import contextmanager from fabric.api import prefix @contextmanager def virtualenv(): with prefix("workon env1"): yield def deploy(): with virtualenv(): run("pip freeze > requirements.txt")

  2. O despliega tu archivo fab y ejecútalo localmente. Esta configuración le permite activar virtualenv para comandos locales o remotos. Este enfoque es poderoso porque funciona en función de la incapacidad local para ejecutar .bashrc utilizando bash -l :

    @contextmanager def local_prefix(shell, prefix): def local_call(command): return local("%(sh)s /"%(pre)s && %(cmd)s/"" % {"sh": shell, "pre": prefix, "cmd": command}) yield local_prefix def write_requirements(shell="/bin/bash -lic", env="env1"): with local_prefix(shell, "workon %s" % env) as local: local("pip freeze > requirements.txt") write_requirements() # locally run("fab write_requirements")