Quiero usar Fabric para implementar el código de mi aplicación web en servidores de desarrollo, preparación y producción. Mi fabfile:
def deploy_2_dev():
deploy('dev')
def deploy_2_staging():
deploy('staging')
def deploy_2_prod():
deploy('prod')
def deploy(server):
print 'env.hosts:', env.hosts
env.hosts = [server]
print 'env.hosts:', env.hosts
Salida de muestra:
host:folder user$ fab deploy_2_dev
env.hosts: []
env.hosts: ['dev']
No hosts found. Please specify (single) host string for connection:
Cuando creo una set_hosts()
tarea como se muestra en los documentos de Fabric , env.hosts está configurado correctamente. Sin embargo, esta no es una opción viable, ni tampoco un decorador. Pasar hosts en la línea de comando daría como resultado en última instancia algún tipo de script de shell que llame al fabfile, preferiría que una sola herramienta hiciera el trabajo correctamente.
Dice en los documentos de Fabric que 'env.hosts es simplemente un objeto de lista de Python'. Según mis observaciones, esto simplemente no es cierto.
¿Alguien puede explicar qué está pasando aquí? ¿Cómo puedo configurar el host para la implementación?
Respuestas:
Hago esto declarando una función real para cada entorno. Por ejemplo:
Usando las funciones anteriores, escribiría lo siguiente para implementarlo en mi entorno de prueba:
... y lo siguiente para implementar en producción:
Lo bueno de hacerlo de esta manera es que las funciones
test
yprod
se pueden usar antes que cualquier función fab, no solo implementar. Es increíblemente útil.fuente
code.fabfile.org
dominio tienen respuestas así.fab A B C
estilo sin que estén definidas como tareas.Utilice roledefs
Elija el rol con -R:
fuente
roledef
? Una entrada adicional del diccionario'password': 'some_password'
parece ignorarse y conduce a un mensaje en tiempo de ejecución.Aquí hay una versión más simple de la respuesta de serverhorror :
fuente
env
variables, no para configurarlas inicialmente. Creo que el uso de roledefs , como sugirió thomie, es más apropiado para definir hosts como stage, dev y test.Estaba atrapado en esto yo mismo, pero finalmente lo descubrí. Simplemente no puede establecer la configuración de env.hosts desde dentro de una tarea. Cada tarea se ejecuta N veces, una para cada Host especificado, por lo que la configuración está fundamentalmente fuera del alcance de la tarea.
Mirando su código anterior, simplemente podría hacer esto:
Lo que parece que haría lo que pretendes.
O puede escribir código personalizado en el ámbito global que analice los argumentos manualmente y establezca env.hosts antes de que se defina la función de la tarea. Por algunas razones, así es como configuré el mío.
fuente
from fabric.api import env
:;env.host_string = "dev"
Desde fab 1.5, esta es una forma documentada de configurar hosts dinámicamente.
http://docs.fabfile.org/en/1.7/usage/execution.html#dynamic-hosts
Cita del documento a continuación.
fuente
A diferencia de otras respuestas, es posible modificar las
env
variables de entorno dentro de una tarea. Sin embargo, estoenv
solo se usará para tareas posteriores ejecutadas con lafabric.tasks.execute
función.Sin incluir las subtareas , se utilizará la configuración de
execute(...)
nivel de móduloenv
o lo que se pase de lafab
CLI.fuente
Necesitas dar
host_string
un ejemplo sería:fuente
Para explicar por qué es incluso un problema. El comando fab está aprovechando la estructura de la biblioteca para ejecutar las tareas en las listas de hosts. Si intenta cambiar la lista de hosts dentro de una tarea, esencialmente está intentando cambiar una lista mientras la itera. O, en el caso de que no tenga hosts definidos, recorra una lista vacía donde el código donde configuró la lista para que se repita nunca se ejecuta.
El uso de env.host_string es una solución para este comportamiento solo en el sentido de que especifica directamente a las funciones con qué hosts conectarse. Esto causa algunos problemas en el sentido de que rehacerá el ciclo de ejecución si desea tener varios hosts para ejecutar.
La forma más sencilla en que la gente crea la capacidad de configurar hosts en tiempo de ejecución es mantener la población de env como una tarea distinta, que configura todas las cadenas de host, usuarios, etc. Luego, ejecutan la tarea de implementación. Se parece a esto:
o
Donde la puesta en escena y la producción son como las tareas que le ha encomendado, pero no llaman a la siguiente tarea por sí mismas. La razón por la que tiene que funcionar así es que la tarea tiene que terminar y salir del bucle (de hosts, en el caso de env None, pero es un bucle de uno en ese punto), y luego tener el bucle terminado los hosts (ahora definidos por la tarea anterior) de nuevo.
fuente
Necesita modificar env.hosts a nivel de módulo, no dentro de una función de tarea. Yo cometí el mismo error.
fuente
Es muy simple. Simplemente inicialice la variable env.host_string y todos los siguientes comandos se ejecutarán en este host.
fuente
Soy totalmente nuevo en Fabric, pero para que Fabric ejecute los mismos comandos en múltiples hosts (por ejemplo, para implementar en múltiples servidores, en un comando), puede ejecutar:
donde el servidor intermedio y el servidor de producción son 2 servidores contra los que desea ejecutar la acción de implementación. Aquí hay un simple fabfile.py que mostrará el nombre del sistema operativo. Tenga en cuenta que fabfile.py debe estar en el mismo directorio donde ejecuta el comando fab.
Esto funciona con la tela 1.8.1 al menos.
fuente
Entonces, para configurar los hosts y hacer que los comandos se ejecuten en todos los hosts, debe comenzar con:
Una vez que estén definidos, ejecute el comando en la línea de comando:
Qué ejecutará la tarea de implementación en todos los servidores enumerados en la función PROD, ya que establece env.hosts antes de ejecutar la tarea.
fuente
Puede asignar
env.hoststring
antes de ejecutar una subtarea. Asigne a esta variable global en un bucle si desea iterar sobre múltiples hosts.Desafortunadamente para usted y para mí, la tela no está diseñada para este caso de uso. Consulte la
main
función en http://github.com/bitprophet/fabric/blob/master/fabric/main.py para ver cómo funciona.fuente
Aquí hay otro patrón de "salto de verano" que permite
fab my_env_1 my_command
uso:Con este patrón, solo tenemos que definir entornos una vez utilizando un diccionario.
env_factory
crea funciones basadas en los nombres clave deENVS
. PuseENVS
su propio directorio y archivosecrets.config.py
para separar la configuración del código de la tela.El inconveniente es que, como está escrito, agregar el
@task
decorador lo romperá .Notas: Usamos en
def func(k=k):
lugar dedef func():
en la fábrica debido a la encuadernación tardía . Obtenemos el módulo en ejecución con esta solución y lo parcheamos para definir la función.secrets.config.py
fabfile.py
fuente
Actualmente, el uso de roles se considera la forma "adecuada" y "correcta" de hacer esto y es lo que "debería" hacerlo.
Dicho esto, si usted es como la mayor parte de lo que "le gustaría" o "desea" es la capacidad de realizar un "sistema retorcido" o cambiar los sistemas de destino sobre la marcha.
Entonces, solo para fines de entretenimiento (!) El siguiente ejemplo ilustra lo que muchos podrían considerar una maniobra arriesgada y, sin embargo, completamente satisfactoria, que es algo como esto:
Luego corriendo:
fuente