Bisakah tugas Python Fabric memanggil tugas lain dan menghormati daftar hostnya?

Saya memiliki fabfile seperti berikut:

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

saya akan melakukan

fab deploy

dan membuatnya setara dengan

fab host1_deploy host2_deploy

Dengan kata lain, jalankan setiap subtugas dan untuk masing-masing subtugas gunakan daftar host yang ditentukannya. Namun, ini tidak berhasil. Sebaliknya, tugas deploy() menginginkan daftar hostnya sendiri yang akan disebarkan ke semua subtugasnya.

Apakah ada cara untuk memperbarui tugas deploy() di sini sehingga ia akan melakukan apa yang saya inginkan sambil membiarkan subtugasnya sendiri sehingga dapat dijalankan satu per satu?


person fabricquestion    schedule 17.03.2011    source sumber


Jawaban (4)


Sejak Fabric 1.3, helper execute kini tersedia untuk melakukan hal ini. Dokumentasinya tersedia di sini: Mengeksekusi dengan cerdas tugas dengan mengeksekusi.

Berikut adalah contoh yang mereka gunakan:

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

Dan kemudian menjalankan migrate dan web dari tugas lain deploy:

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

Dan ini akan menghormati daftar peran dan host yang dimiliki tugas-tugas tersebut.

person Mitchell    schedule 17.11.2011
comment
Apakah mungkin menambahkan peran ke metode kelas? Saya menggunakan kelas untuk tugas-tugas fabric - person Francesco Della Vedova; 28.11.2013
comment
Tautan ke dokumentasi rusak. Ini yang terbaru: docs.fabfile .org/en/1.8/usage/ - person krd; 22.05.2014

Ini payah tetapi berfungsi pada 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()

inilah kode pengujian saya:

@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')
person Evan R.    schedule 12.07.2011

Mungkin ada cara yang lebih baik untuk menanganinya, tetapi Anda dapat meneruskan kedua host ke deploy(), lalu di host1_deploy() dan host2_deploy() periksa 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()
person pwan    schedule 18.03.2011

Coba yang ini. Tentunya Anda ingin mengganti lokal dengan run atau sudo. Kuncinya adalah dekorator @hosts kosong untuk 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()
person Charles Hooper    schedule 28.06.2011