Может ли задача Python Fabric вызывать другие задачи и уважать их списки хостов? - PullRequest
31 голосов
/ 18 марта 2011

У меня есть файл, подобный следующему:

@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()

Я хотел бы сделать

fab deploy

и сделать его эквивалентным

fab host1_deploy host2_deploy

ВДругими словами, запустите каждую из подзадач и для каждого используйте список хостов, который он указывает.Однако это не работает.Вместо этого задача deploy () хочет иметь собственный список хостов, который она распространит на все свои подзадачи.

Есть ли способ обновить задачу deploy () здесь, чтобы она делала то, что я хочу, оставляяодни только подзадачи, чтобы их можно было запускать индивидуально?

Ответы [ 4 ]

30 голосов
/ 18 ноября 2011

Начиная с Fabric 1.3, помощник execute теперь доступен для этого.Документация доступна здесь: Интеллектуальное выполнение задач с помощью команды execute .

Вот пример, который они используют:

from fabric.api import run, roles

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

И затем для запуска migrate и web из другой задачи deploy:

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

И это будет уважать списки ролей и хостов, которые есть у этих задач.

3 голосов
/ 13 июля 2011

Это хромает, но работает с 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()

вот мой тестовый код:

@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')
1 голос
/ 28 июня 2011

Попробуйте это. Очевидно, вы хотите заменить локальный на run или sudo. Ключ пустого @hosts декоратора для 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()
1 голос
/ 18 марта 2011

Возможно, есть лучший способ справиться с этим, но вы можете передать оба хоста в deploy (), а затем в host1_deploy () и host2_deploy () проверить env.host:

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()
...