Al momento de escribir este artículo, la rama v2 tiene una clase Group
que debería ser capaz de servir como las unidades antes conocidas como 'roles', también conocido como "un montón de hosts para hacer cosas con / en".
Sin embargo, todavía no existe una forma específica de organizar o etiquetar objetos Group
; está lo suficientemente "hecho" para el caso de uso de API puro de usuarios avanzados que desean desarrollar su propia forma específica de crearlos, pero carece de algo para usuarios orientados a CLI o personas intermedias que desean algo con un marco para construir.
Dicho de otra manera, a menos que esté trabajando exclusivamente con la API, tener objetos de grupo en algún lugar es inútil si la CLI o los bits de llamada de tareas no tienen forma de encontrarlos.
En v1, los roles eran efectivamente un único espacio de nombres plano que asignaba etiquetas de cadena simples a lo que serían Grupos en v2, y podían seleccionarse en la CLI en tiempo de ejecución ( fab --roles=web,db
) y / o registrarse como destinos predeterminados para tareas ( @task('db') \n def migrate():
), al igual que los hosts.
Los usuarios los definieron en env.roledefs
, un diccionario simple; cualquier funcionalidad intermedia a avanzada giraba en torno a modificarla, generalmente en tiempo de ejecución (a través de una tarea previa o subrutina), a veces en el momento de carga del módulo.
Group
sy / o Connection
s.Lexicon
lugar de un dict
.db
, web
, lb
, pero luego un nombre de segundo nivel llamado prod
que es siempre la unión de los otros tres. Olvidé si agregué eso a Lexicon
todavía. Es posible que haya otras subclases de mapas que ya lo hagan.if cxn in group
funcionaría incluso si cxn
es un objeto distinto del miembro igual dentro de group
.db
"@group
como @task
, y las funciones no son unidades de trabajo ejecutables, sino que producen objetos de grupo.De la lista de correo:
Mejoramos nuestra propia API REST interna que llena env.roledefs dinámicamente dependiendo del proyecto que se está implementando y confiamos en gran medida en no incrustar cadenas de host en el fabfile del proyecto o especificarlas en CLI.
Nuestros casos de uso son:
EnvironmentDatabaseAPIClient(
'https://rest.api.url/schema/',
env.service_name,
).apply_env()
Número de entornos de servidor: múltiples entornos de prueba (algunos de ellos son privados, otros públicos) y múltiples entornos de producción (para diferentes clientes). Cada entorno consta de uno o más hosts y se asigna a la función de la estructura.
Cada servicio ( env.service_name
en el ejemplo anterior) tiene un conjunto diferente de entornos.
También tenemos meta-roles (grupos de roles). Tienen el prefijo group-
: group-production
, group-test
, group-external
, group-internal
, group-all
. Esto nos permite implementar en múltiples roles de servidor sin especificarlos uno por uno, por ejemplo group-all
implementa en todos los roles, tanto de producción como de prueba.
Tenemos tareas especiales de estructura para imprimir información sobre grupos de roles, roles y hosts.
También confiamos en gran medida en el mapeo inverso de las cadenas de host a los nombres de los roles (las cadenas de hosts son únicas por service_name). Se utiliza para el registro y las notificaciones de implementación. Básicamente, registramos las implementaciones de servicios en cada host y enviamos una notificación de Slack cuando el servicio se ha implementado en todos los hosts en un rol. El servidor EnvironmentDatabaseAPI es responsable de esto (mantiene los registros y el estado de implementación). Esto se hace decorando las tareas de la tela con un decorador que envía env.host
, env.port
y env.service_name
(más información de confirmación) al servidor API.
Planeamos agregar la autenticación de implementación en el futuro, también es muy probable que extraigaremos más variables env
del servidor para que estén disponibles dentro del contexto de la tarea.
¡Gracias @ max-arnold! También reconozco muchos de mis propios casos de uso en el pasado. Recuerdo que el bit de mapeo inverso en particular apareció en v1 varias veces, así que lo agregué a la lista.
Para que Fabric v2 me sea útil, necesitaría una forma de decirle a fab
qué conjunto de hosts ejecutar una tarea.
Anteriormente, definí roles y luego ejecuté fab -R ...
. (En realidad, los roles se definieron mediante programación utilizando un rango de direcciones IP, pero eso no es un requisito y una lista estática dentro de un archivo YAML estaría bien).
No encuentro un equivalente en Fabric v2, y tampoco pude emular esta función usando:
fabric.yaml
que contieneactive_hostset: null
hostsets:
myhostset:
- ...
active_hostset = config["hostsets"][config["active_hostset"]]
en fabfile.py
env INVOKE_ACTIVE_HOSTSET=myhostset fab ...
En lugar de la lista esperada de hosts, obtengo KeyError: 'active_hostset'
.
Asignamos diferentes conjuntos de hosts a cada rol para cada uno de nuestros entornos en fabric v1, y el entorno se configura ejecutando una tarea role.environment:staging
para especificarlo. Entonces, esta tarea influye en los hosts utilizados por las siguientes tareas.
En la v2 intentamos usar una Tarea personalizada, pero el problema es que Executor.expand_calls
ejecuta antes de que se ejecute nuestra tarea role.environment
y, por lo tanto, ninguna de las siguientes tareas conoce el entorno para construir dinámicamente sus listas de hosts.
Hacer de Executor.expand_calls
un generador permite que la ejecución de tareas influya en la ejecución de tareas posteriores. Entonces, mi ejemplo anterior funciona, donde tenemos un Task
que necesita conocer su entorno para expandir adecuadamente los roles a los hosts. por ejemplo, fab role.environment dev deploy.app
- la tarea role.environment
ahora se ejecuta antes de que deploy.app
se expanda, por lo que deploy.app
conoce el entorno y puede configurar sus hosts y luego se expande a el conjunto correcto de tareas.
Hice un prototipo de esto en mis horquillas:
https://github.com/pyinvoke/invoke/compare/master...rectalogic : expand-generator
https://github.com/fabric/fabric/compare/master...rectalogic : expand-generator
Hola, no sé qué pasó con este software después de muchos años, pero realmente extrañé el concepto de "roles" en [email protected] , especialmente cuando se ejecuta $ fab -R dev
También usamos roles para representar el mismo conjunto de operaciones en diferentes entornos. ¿Quizás sería útil separar el concepto de un rol con nombre y un entorno con nombre? Como en el rol web en el entorno de desarrollo.
Comentario más útil
Hola, no sé qué pasó con este software después de muchos años, pero realmente extrañé el concepto de "roles" en [email protected] , especialmente cuando se ejecuta
$ fab -R dev