2010-06-23 6 views
22

Il s'agit d'une question très spécifique à Fabric, mais les pirates informatiques plus expérimentés pourraient être en mesure de répondre à cette question, même s'ils ne connaissent pas Fabric.Comment découvrir le rôle actuel dans Python Fabric

Je suis en train de spécifier le comportement différent dans une commande en fonction du rôle qu'il est en cours d'exécution pour, à savoir:

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

je Hacking cela avec des fonctions comme celui-ci:

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

Mais ce n'est évidemment pas très élégant et je viens de découvrir les rôles, donc ma question est:

Comment puis-je savoir à quel rôle appartient une instance actuelle?

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

Merci!

Répondre

4

Mise à jour: Juste vérifié the source code et il semble que c'était déjà disponible dès 1.4.2!

update 2: Cela semble pas à travailler lors de l'utilisation du décorateur @roles (en 1.5.3)! Cela ne fonctionne que lorsque vous spécifiez les rôles à l'aide de l'indicateur de ligne de commande -R. Pour la structure 1.5.3, les rôles actuels sont directement disponibles dans `fabric.api.env.roles '. Par exemple:

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 

Sortie test sur la console:

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

Done. 

Ou:

› 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. 

Avec cela, nous pouvons faire une simple tâche de tissu essai in:

@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

merci pour cette mise à jour. ma vieille réponse est très démodée/non pertinente ces jours-ci. – rdrey

+0

Cela ne fonctionne pas non plus avec le format de ligne de commande 'fab testrole: roles =" staging, prod "'. Trop limité pour une utilisation réelle. – Rockallite

+0

@Rockallite C'est la syntaxe pour passer des params aux tâches. J'ai effectivement trouvé [votre exemple dans les docs] (http://docs.fabfile.org/fr/1.8/usage/fab.html?highlight=roles#roles-and-hosts). Mais je n'ai pas pu utiliser cette syntaxe pour spécifier les rôles (voir [transcript] (https://gist.github.com/exhuma/8348976)). Pourquoi ne pas simplement utiliser '-R'? Est-il possible que les documents de tissu sont périmés? – exhuma

17

Pour tout le monde jamais avec cette question, voici ma solution:

La clé était de trouver env.host_string.

Voici comment je redémarre différents types de serveurs avec une seule commande:

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) 

profiter!

+4

Cela échouera si j'ai le même hôte associé à différents rôles et que je veux faire des choses différentes selon le rôle actuellement exécuté:/ – Tadeck

+0

Le tissu a beaucoup changé depuis que j'ai demandé/répondu à cette question, donc je ne Comprenez votre problème. Il est facile de traiter avec des hôtes dans plusieurs rôles avec mon code ci-dessus, il suffit de changer if/elif en si, si, si ... Si vous voulez savoir comment faire fonctionner une commande pour un rôle spécifique, consultez cette nouvelle fonctionnalité: http://docs.fabfile.org/fr/1.4.1/usage/execution.html#intelligently-executing-tasks-with-execute – rdrey

+0

Je crois qu'il y a une sorte de malentendu;) Ce que je disais c'est que si vous avez un hôte pour plusieurs rôles (par exemple 'env.roledefs = {'apache': ['host1', 'host2'], 'APE': ['host1']}' et vous exécutez votre script pour un rôle spécifique , vous n'avez pas la possibilité de vérifier quel rôle est en cours de traitement.Bien sûr vous pouvez utiliser 'execute()' pour créer des "méta-tâches", mais cela ne résout pas le problème (je ne dirais pas que c'est un problème). Je crois que le tissu n'a pas été conçu juste pour cela et que vous devez le faire d'une autre manière (à moins qu'il n'ait été conçu pour cela). – Tadeck

11

Je n'ai pas testé, mais pourrait fonctionner:

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

cela fonctionne. belle fonction d'aide. – Banjer

+0

utilisez simplement 'env.roles' (voir ma réponse sur cette question). – exhuma

6

Le env.roles vous donnera les rôles spécifiés par -R flag ou codés en dur dans le script lui-même. Il ne contiendra pas les rôles spécifiés par tâche en utilisant la ligne de commande ou en utilisant le décorateur @roles. Il n'y a actuellement aucun moyen d'obtenir ce genre d'information.

La prochaine version de tissu (1.9 probablement) fournira l'attribut env.effective_roles avec exactement ce que vous voulez - les rôles utilisés pour la tâche actuellement exécutée. Le code pour cela a déjà été fusionné en master.

Jetez un oeil à this issue.

Questions connexes