31 Stimmen

Kann ein Python Fabric Task andere Tasks aufrufen und deren Hosts-Listen respektieren?

Ich habe ein Fabfile wie das folgende:

@hosts('host1')
def host1_deploy():
    """Some logic that is specific to deploying to host1"""

@hosts('host2')
def host2_deploy():
    """Some logic that is specific to deploying to host2"""

def deploy():
    """"Deploy to both hosts, each using its own logic"""
    host1_deploy()
    host2_deploy()

Ich möchte Folgendes tun

fab deploy

und gleichwertig sein mit

fab host1_deploy host2_deploy

Mit anderen Worten: Führen Sie jede der Unteraufgaben aus und verwenden Sie für jede die darin angegebene Liste von Hosts. Dies funktioniert jedoch nicht. Stattdessen möchte die deploy()-Aufgabe ihre eigene Liste von Hosts, die sie an alle ihre Unteraufgaben weitergibt.

Gibt es eine Möglichkeit, die deploy() Aufgabe hier zu aktualisieren, so dass es tut, was ich will, während die Unteraufgaben allein lassen, so dass Sie einzeln ausgeführt werden können?

31voto

Mitchell Punkte 32451

Seit Fabric 1.3 ist die execute Helfer ist jetzt verfügbar, um genau dies zu tun. Die Dokumentation ist hier verfügbar: Intelligente Ausführung von Aufgaben mit execute .

Hier ist das Beispiel, das sie verwenden:

from fabric.api import run, roles, execute

env.roledefs = {
    'db': ['db1', 'db2'],
    'web': ['web1', 'web2', 'web3'],
}

@roles('db')
def migrate():
    # Database stuff here.
    pass

@roles('web')
def update():
    # Code updates here.
   pass

Und dann beide ausführen migrate y web von einer anderen Aufgabe deploy :

def deploy():
    execute(migrate)
    execute(update)

Dabei werden die für diese Aufgaben geltenden Rollen und Gastgeberlisten berücksichtigt.

3voto

Evan R. Punkte 2947

Das ist lahm, aber es funktioniert ab Fabric 1.1.2

def host1_deploy():
    """Some logic that is specific to deploying to host1"""
    if env.host in ["host1"]:
        pass #this is only on host2

def host2_deploy():
    """Some logic that is specific to deploying to host2"""
    if env.host in ["host2"]:
        pass #this is only on host2

def deploy():
    """"Deploy to both hosts, each using its own logic"""
    host1_deploy()
    host2_deploy()

Hier ist mein Testcode:

@task
@roles(["prod_web","prod_workers"])
def test_multi():
    test_multi_a()
    test_multi_b()

def test_multi_a():
    if env.host in env.roledefs["prod_web"]:
        run('uname -a')

def test_multi_b():
    if env.host in env.roledefs["prod_workers"]:
        run('uname -a')

1voto

pwan Punkte 2894

Es gibt wahrscheinlich einen besseren Weg, dies zu handhaben, aber Sie könnten beide Hosts an deploy() übergeben und dann in host1_deploy() und host2_deploy() env.host überprüfen:

def host1_deploy():
    if env.host in ['host1']:
         run(whatever1)

def host2_deploy():
    if env.host in ['host2']:
         run(whatever2)

@hosts('host1','host2')
def deploy():
    host1_deploy()
    host2_deploy()

1voto

Charles Hooper Punkte 2674

Versuchen Sie dies. Offensichtlich wollen Sie local durch run ou sudo . Der Schlüssel ist die leere @hosts Dekorateur für deploy

from fabric.api import local
from fabric.decorators import hosts

@hosts('host1')
def host1_deploy():
    """Some logic that is specific to deploying to host1"""
    local('echo foo')

@hosts('host2')
def host2_deploy():
    """Some logic that is specific to deploying to host2"""
    local('echo bar')

@hosts('')
def deploy():
    """"Deploy to both hosts, each using its own logic"""
    host1_deploy()
    host2_deploy()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X