Activar un virtualenv a través de fabric como usuario de implementación
Quiero ejecutar mi script fabric 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 uso el comando workon de virtualenvwrapper que obtiene el archivo activate y el archivo postactivate me pondrá en la carpeta del proyecto. En este caso, parece que debido a que la tela se ejecuta desde dentro de la cáscara, el control es ceder a la tela, así que no puedo usar bash fuente integrada en 'source source ~/.virtualenv/myvenv/bin/activate'
¿Alguien tiene un ejemplo y una explicación de cómo han hecho esto?
8 answers
Ahora mismo, puedes hacer lo que yo hago, que es kludgy pero funciona perfectamente bien* (este uso asume que estás usando virtualenvwrapper which que deberías ser which pero puedes sustituirlo fácilmente en la llamada 'source' bastante 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 prefix
context manager que utiliza 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 haya casos en los que el uso de la command1 && command2
enfoque puede explotar en usted, tales como cuando command1
falla (command2
nunca se ejecutará) o si command1
no está correctamente escapado y contiene caracteres especiales de shell, y así sucesivamente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-25 00:21:46
Como una actualización del pronóstico de bitprophet: Con Fabric 1.0 puede hacer uso de prefix() y sus propios gestores 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')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-01 12:45:46
Solo estoy usando una función de envoltura simple virtualenv() que se puede llamar en lugar de run(). 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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-04 07:48:49
virtualenvwrapper
puede hacer esto un poco más simple
-
Usando el enfoque de @nh2 (este enfoque también funciona cuando se usa
local
, pero solo para instalaciones virtualenvwrapper dondeworkon
está en$PATH
, en otras palabras Windows 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")
-
O implemente su archivo fab y ejecútelo localmente. Esta configuración le permite activar el virtualenv para comandos locales o remotos. Este enfoque es poderoso porque funciona alrededor de la incapacidad de
local
para ejecutarse .bashrc usandobash -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")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-18 16:38:21
Este es mi enfoque sobre el uso de virtualenv
con implementaciones locales.
Usando el gestor de contexto path() de fabric puedes 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')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-10 11:51:45
Gracias a todas las respuestas publicadas y me gustaría añadir 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:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-07 07:02:36
Aquí está el código para un decorador que resultará en el uso de 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")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-27 22:38:03
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 fabric o instalar nuevos paquetes de sistema operativo:
/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 bajo el entorno.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-17 06:35:46