2010-06-23 9 views
22

Questa è una domanda specifica di Fabric, ma gli hacker più esperti di python potrebbero essere in grado di rispondere a questo, anche se non conoscono Fabric.Come scoprire il ruolo corrente in Fabric Python

Sto cercando di specificare il comportamento diverso in un comando a seconda di quale ruolo è in esecuzione per, vale a dire:

def restart(): 
    if (SERVERTYPE == "APACHE"): 
     sudo("apache2ctl graceful",pty=True) 
    elif (SERVERTYPE == "APE"): 
     sudo("supervisorctl reload",pty=True) 

mi era hacking questo con funzioni come questo:

def apache(): 
    global SERVERTYPE 
    SERVERTYPE = "APACHE" 
    env.hosts = ['xxx.xxx.com'] 

Ma Ovviamente non è molto elegante e ho appena scoperto ruoli, quindi la mia domanda è:

Come faccio a capire a quale ruolo appartiene un'istanza corrente?

env.roledefs = { 
    'apache': ['xxx.xxx.com'], 
    'APE': ['yyy.xxx.com'], 
} 

Grazie!

risposta

4

Aggiornamento: appena controllato the source code e sembra che questo era già disponibile fin da 1.4.2!

aggiornamento 2: Questo non sembra a lavorare quando si utilizza il @roles decoratore (in 1.5.3)! Funziona solo quando si specificano i ruoli utilizzando il flag della riga di comando -R.

Per fabric 1.5.3 i ruoli correnti sono direttamente disponibili in `fabric.api.env.roles '. Per esempio:

import fabric.api as fab 

fab.env.roledefs['staging'] = ['bbs-evolution.ipsw.dt.ept.lu'] 
fab.env.roledefs['prod'] = ['bbs-arbiter.ipsw.dt.ept.lu'] 


@fab.task 
def testrole(): 
    print fab.env.roles 

uscita di test sulla console:

› fab -R staging testrole 
[bbs-evolution.ipsw.dt.ept.lu] Executing task 'testrole' 
['staging'] 

Done. 

Oppure:

› fab -R staging,prod testrole 
[bbs-evolution.ipsw.dt.ept.lu] Executing task 'testrole' 
['staging', 'prod'] 
[bbs-arbiter.ipsw.dt.ept.lu] Executing task 'testrole' 
['staging', 'prod'] 

Done. 

Con questo, possiamo fare un semplice test in in un compito di tessuto:

@fab.task 
def testrole(): 
    if 'prod' in fab.env.roles: 
     do_production_stuff() 
    elif 'staging' in fab.env.roles: 
     do_staging_stuff() 
    else: 
     raise ValueError('No valid role specified!') 
+0

grazie per questo aggiornamento. la mia vecchia risposta è molto antiquata/irrilevante in questi giorni. – rdrey

+0

Anche questo non funziona con il formato a riga di comando 'fab testrole: roles =" staging, prod "'. Troppo limitato per l'uso effettivo. – Rockallite

+0

@Rockallite Questa è la sintassi per passare in param alle attività. Ho effettivamente trovato [il tuo esempio nei documenti] (http://docs.fabfile.org/en/1.8/usage/fab.html?highlight=roles#roles-and-hosts). Ma non ero in grado di usare quella sintassi per specificare i ruoli (vedi [trascrizione] (https://gist.github.com/exhuma/8348976)). Perché non usare semplicemente '-R'? È possibile che i documenti del tessuto non siano aggiornati? – exhuma

17

Per tutti gli altri sempre con questa domanda, ecco la mia soluzione:

La chiave era trovare env.host_string.

Questo è come mi rimetto in moto diversi tipi di server con un solo comando:

env.roledefs = { 
    'apache': ['xxx.xxx.com'], 
    'APE': ['yyy.xxx.com'] 
} 

def apache(): 
    env.roles = ['apache'] 

... 

def restart(): 
    if env.host_string in env.roledefs['apache']: 
     sudo("apache2ctl graceful", pty=True) 
    elif env.host_string in env.roledefs['APE']: 
     sudo ("supervisorctl reload", pty=True) 

godere!

+4

Questo fallirà se ho lo stesso host associato a diversi ruoli e voglio fare cose diverse a seconda di quale ruolo è attualmente eseguito:/ – Tadeck

+0

Il tessuto è cambiato molto da quando ho chiesto/risposto a questa domanda, quindi non lo so capisci il tuo problema È facile gestire gli host in più ruoli con il mio codice sopra, semplicemente cambia if/elif in if, if, if ... Se vuoi sapere come far funzionare un comando solo per un ruolo specifico, dai un'occhiata a questo nuovo funzionalità: http://docs.fabfile.org/en/1.4.1/usage/execution.html#intelligently-executing-tasks-with-execute – rdrey

+0

Credo che ci sia un qualche tipo di malinteso;) Quello che stavo dicendo è che se si dispone di un host per più ruoli (ad esempio 'env.roledefs = {'apache': ['host1', 'host2'], 'APE': ['host1']}' e si esegue lo script per un ruolo specifico non si ha la possibilità di controllare quale ruolo è in fase di elaborazione. Naturalmente è possibile usare 'execute()' per creare "meta task", ma questo non risolve il problema (non lo chiamerei un problema). Credo che Fabric non sia stato solo progettato per questo e devi affrontarlo in qualche altro modo (a meno che non sia stato progettato per questo?). – Tadeck

11

non ho la prova, ma potrebbe funzionare:

def _get_current_role(): 
    for role in env.roledefs.keys(): 
     if env.host_string in env.roledefs[role]: 
      return role 
    return None 
+1

funziona. bella funzione di aiuto. – Banjer

+0

usa semplicemente 'env.roles' (vedi la mia risposta a questa domanda). – exhuma

6

env.roles ti darà i ruoli specificati da -R flag o hardcoded nello script stesso. Non conterrà i ruoli specificati per attività utilizzando la riga di comando o utilizzando il decoratore @roles. Al momento non c'è modo di ottenere questo tipo di informazioni.

La prossima versione di tessuto (1.9 probabilmente) fornirà l'attributo env.effective_roles esattamente con quello che si desidera - i ruoli utilizzati per l'attività attualmente eseguita. Il codice per questo è già stato fuso in master.

Dai un'occhiata allo this issue.

Problemi correlati