130 votes

Activer un virtualenv via le tissu que de déployer de l'utilisateur

Je veux exécuter mon tissu script en local, qui à son tour, se connecter à mon serveur, changer d'utilisateur, de déployer, d'activer les projets .virtualenv, qui va changer dir pour le projet et d'émettre un git pull.

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

Je l'utilise généralement l'travaillons sur commande à partir de virtualenvwrapper les sources de l'activer fichier et le postactivate fichier m'a mis dans le dossier du projet. Dans ce cas, il semble que, parce que le tissu s'étend de l'intérieur de la coquille, de contrôle, c'est de donner plus de tissu, donc je ne peux pas utiliser bash de source intégré à '$source ~/.virtualenv/myvenv/bin/activate"

Quelqu'un a un exemple et une explication de la façon dont ils l'ont fait?

138voto

nh2 Points 4421

Une mise à jour de bitprophet prévisions: Avec Tissu 1.0 vous pouvez utiliser le préfixe() et votre propre contexte gestionnaires.

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')

96voto

bitprophet Points 1037

Dès maintenant, vous pouvez faire ce que je fais, ce qui est encombrants mais fonctionne parfaitement* (cette utilisation suppose que vous utilisez virtualenvwrapper -- ce qui devrait être -- mais vous pouvez facilement remplacer, dans le plus long "source" appel que vous avez mentionné, si ce n'):

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

Depuis la version 1.0, le Tissu a un prefix gestionnaire de contexte qui utilise cette technique de sorte que vous pouvez par exemple:

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

* Il y a certainement des cas où l'aide de l' command1 && command2 approche peut sauter sur vous, comme lors de l' command1 d'échec (command2 ne sera jamais) ou si command1 n'est pas correctement échappé et contient coque spéciale caractères, et ainsi de suite.

18voto

ehc Points 378

Je suis juste à l'aide d'une simple fonction wrapper virtualenv() peut être appelée à la place de run(). Il n'utilise pas le cd gestionnaire de contexte, de sorte que les chemins relatifs ne peuvent être utilisés.

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)

9voto

Mr. Dave Points 379

virtualenvwrapper peut rendre cela un peu plus simple

  1. À l'aide de @nh2 approche cette approche fonctionne aussi lors de l'utilisation d' local, mais seulement pour virtualenvwrapper les installations où l' workon est $PATH, en d'autres termes, Windows)

    from contextlib import contextmanager
    
    @contextmanager
    def virtualenv():
        with prefix("workon env1"):
            yield
    
    def deploy():
        with virtualenv():
            run("pip freeze > requirements.txt")
    
  2. Ou de déployer votre fab fichier et de l'exécuter localement. Cette configuration permet d'activer le virtualenv pour les locaux ou des commandes à distance. Cette approche est puissante parce qu'elle travaille autour de la locals'incapacité à exécuter .bashrc l'aide d' 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")
    

8voto

darklow Points 456

C'est mon approche sur l'utilisation de l' virtualenv locaux déploiements.

À l'aide de tissu du chemin (la) gestionnaire de contexte vous pouvez exécuter pip ou python avec les binaires 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')

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X