Frage

Ich möchte mein Fabric -Skript lokal ausführen, das sich wiederum auf meinem Server anmelden, den Benutzer wechselt, um die Projekte zu aktivieren, die Projekte. Virtualenv, die die DIR zum Projekt ändern und einen Git -Zug ausstellen.

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

Ich verwende normalerweise den Workon -Befehl von virtualenvWrapper, der die Aktivierungsdatei bezieht, und die postaktivierte Datei wird mich in den Projektordner versetzt. In diesem Fall scheint es, dass der Stoff aus der Schale, die die Kontrolle über den Stoff übergibt, so dass ich Bashs Quelle nicht zu '$ source ~/.virtuualenv/myvenv/bin/activate' verwenden kann.

Hat jemand ein Beispiel und eine Erklärung dafür, wie er das getan hat?

War es hilfreich?

Lösung

Im Moment können Sie das tun, was ich tue, was kludgy ist, aber perfekt gut funktioniert* (in dieser Verwendung wird davon ausgegangen , wenn nicht):

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

Seit Version 1.0 hat Fabric a prefix Kontextmanager Dies verwendet diese Technik, damit Sie zum Beispiel:

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

* Es wird zwangsläufig Fälle geben, in denen die Verwendung der verwendet werden command1 && command2 Annäherung kann Sie aufblasen, z. B. wann command1 scheitert (command2 wird niemals laufen) oder wenn command1 Ist nicht richtig entkommen und enthält spezielle Muschelzeichen und so weiter.

Andere Tipps

Als Update für die Prognose von BitProphet: Mit Fabric 1.0 können Sie verwenden Präfix() und Ihre eigenen Kontextmanager.

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

Ich verwende nur eine einfache Wrapper -Funktion virtualenv (), die anstelle von run () aufgerufen werden kann. Der CD -Kontext -Manager verwendet nicht, sodass relative Pfade verwendet werden können.

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 kann das etwas einfacher machen

  1. Verwenden von @NH2s Ansatz (dieser Ansatz funktioniert auch bei der Verwendung local, aber nur für VirtualenvWrapper -Installationen wo workon ist in $PATH, mit anderen Worten - 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. Oder stellen Sie Ihre fabelhafte Datei bereit und führen Sie diese lokal aus. Mit diesem Setup können Sie das Virtualenv für lokale oder Remote -Befehle aktivieren. Dieser Ansatz ist mächtig, weil er herum funktioniert localUnfähigkeit, .bashrc mithilfe zu laufen 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")
    

Dies ist mein Ansatz bei der Verwendung virtualenv mit lokalen Bereitstellungen.

Mit Stoffs Weg() Kontextmanager können Sie ausführen pip oder python mit Binärdateien von 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')

Vielen Dank an alle geposteten Antworten und ich möchte dafür noch eine Alternative hinzufügen. Es gibt ein Modul, Stoff-Virtualenv, die die Funktion als denselben Code liefern kann:

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

Stoff-Virtualenv nutzt von fabric.context_managers.prefix, was vielleicht ein guter Weg sein könnte :)

Wenn Sie die Pakete in die Umgebung installieren möchten oder Befehle entsprechend den Paketen in der Umgebung ausführen möchten, habe ich diesen Hack gefunden, um mein Problem zu lösen, anstatt komplexe Stoffmethoden zu schreiben oder neue Betriebssystempakete zu installieren:

/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

Auf diese Weise müssen Sie die Umgebung möglicherweise nicht aktivieren, aber Sie können Befehle unter der Umgebung ausführen.

Hier ist Code für einen Dekorateur, der zur Verwendung einer virtuellen Umgebung für jeden Run/Sudo -Anruf führt:

# 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

Und dann, um den Dekorateur zu verwenden, ist die Reihenfolge der Dekorateure wichtig:

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

Dieser Ansatz hat für mich funktioniert, Sie können dies auch anwenden.

from fabric.api import run 
# ... other code...
def install_pip_requirements():
    run("/bin/bash -l -c 'source venv/bin/activate' "
        "&& pip install -r requirements.txt "
        "&& /bin/bash -l -c 'deactivate'")

Annahme venv Ist Ihr virtuelles Envis -Verzeichnis und fügen Sie diese Methode hinzu, wo immer geeignet sind.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top