2010-06-23 9 views
22

Esta es una pregunta muy muy Fabric, pero los hackers python más experimentados podrían ser capaces de responder a esto, incluso si no conocen Fabric.Cómo descubrir el rol actual en Python Fabric

Estoy tratando de especificar el comportamiento diferente en un comando en función del papel que se está ejecutando para, es decir:

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

estaba hackeando esto con funciones como ésta:

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

Pero eso obviamente no es muy elegante y acabo de descubrir roles, entonces mi pregunta es:

¿Cómo puedo averiguar a qué rol pertenece una instancia actual?

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

Gracias!

Respuesta

4

Actualización: acabo de comprobar the source code y parece que esto ya estaba disponible ya en 1.4.2!

actualización 2: Esto parece no a funcionar cuando se utiliza el decorador @roles (en 1.5.3)! Solo funciona cuando se especifican los roles utilizando el indicador de línea de comando -R.

Para la tela 1.5.3 los roles actuales están directamente disponibles en `fabric.api.env.roles '. Por ejemplo:

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 

salida de prueba en la consola:

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

Done. 

O:

› 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 esto, podemos hacer un simple análisis de in en una tarea de tela:

@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

gracias por esta actualización. mi respuesta anterior está muy desactualizada/irrelevante en estos días. – rdrey

+0

Esto tampoco funciona con el formato de línea de comando 'fab testrole: roles =" staging, prod "'. Demasiado limitado para el uso real. – Rockallite

+0

@Rockallite Esa es la sintaxis para pasar en params a las tareas. De hecho, encontré [su ejemplo en los documentos] (http://docs.fabfile.org/en/1.8/usage/fab.html?highlight=roles#roles-and-hosts). Pero no pude usar esa sintaxis para especificar roles (ver [transcripción] (https://gist.github.com/exhuma/8348976)). ¿Por qué no simplemente usar '-R'? ¿Es posible que los documentos de la tela estén desactualizados? – exhuma

17

Para todos los demás nunca con esta pregunta, aquí está mi solución:

La clave fue encontrar env.host_string.

Esta es la forma en que reinicio diferentes tipos de servidores 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) 

disfrutar!

+4

Esto fallará si tengo el mismo host asociado a diferentes roles y quiero hacer diferentes cosas dependiendo de qué rol se está ejecutando actualmente:/ – Tadeck

+0

La tela ha cambiado mucho desde que pregunté/contesté esta pregunta, así que realmente no entiende tu problema Es fácil tratar con hosts en múltiples roles con mi código anterior, simplemente cambie if/elif en if, if, if ... Si desea saber cómo hacer que un comando funcione solo para un rol específico, revise este nuevo funcionalidad: http://docs.fabfile.org/en/1.4.1/usage/execution.html#intelligently-executing-tasks-with-execute – rdrey

+0

Creo que hay algún tipo de malentendido;) Lo que estaba diciendo es que si tiene un host para múltiples roles (ej. 'env.roledefs = {'apache': ['host1', 'host2'], 'APE': ['host1']}' y ejecuta su script para un rol específico , no tiene la capacidad de verificar qué rol se está procesando específicamente. Por supuesto, puede usar 'execute()' para crear "meta tareas", pero esto no resuelve el problema (no lo llamaría problema). Creo que Fabric no solo fue diseñado para eso y que debe lidiar con él de alguna otra forma (a menos que haya sido diseñado para ello). – Tadeck

11

no he probado, pero podría funcionar:

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

funciona. buena función de ayuda. – Banjer

+0

simplemente use 'env.roles' (vea mi respuesta a esta pregunta). – exhuma

6

El env.roles le dará los roles especificados por el distintivo -R o codificado en el propio guión. No contendrá los roles especificados por tarea usando la línea de comando o usando el decorador @roles. Actualmente no hay forma de obtener este tipo de información.

El siguiente lanzamiento de tela (1.9 probablemente) proporcionará el atributo env.effective_roles con exactamente lo que desea: los roles que se utilizan para la tarea ejecutada actualmente. El código para eso ya se ha fusionado en maestro.

Eche un vistazo a this issue.

Cuestiones relacionadas