Tengo un montón de fabfiles de Fabric 1 que establecen env
. Actualmente no es obvio migrar ese código a Fabric 2. La documentación hace referencia, por ejemplo, a connect_kwargs
pero no hay mucho sobre cómo o dónde configurarlo. Después de leer los documentos de Invoke, no parece que pueda usar ninguna de las opciones de configuración de YAML / JSON ya que necesito ejecutar código (en el siguiente ejemplo, usando keyring
para recuperar contraseñas).
Parecía que algo así como moverlo todo a un archivo fabric.py
podría funcionar:
import subprocess
import sys
from getpass import getuser
import os
domain = os.environ.get("DOMAIN", "loctest")
def get_config():
user = getuser()
try:
password = subprocess.check_output(["keyring", "get", domain, user]).strip()
print("Loaded %s password for %s from keyring" % (domain, user))
except subprocess.CalledProcessError:
print(
"Unable to set password using `keyring` (is it in your PATH?) — expect to be nagged",
file=sys.stderr,
)
return {'user': user, 'password': password}
connect_kwargs = get_config()
Desafortunadamente, eso obtiene TypeError: can't pickle module objects
. Configurar __all__
no es suficiente para evitar eso, pero mover todo a la función parece estar funcionando:
def get_config():
import subprocess
import sys
from getpass import getuser
import os
domain = os.environ.get("DOMAIN", "loctest")
user = os.environ.get("USER", getuser())
try:
password = subprocess.check_output(["keyring", "get", domain, user]).strip()
print("Loaded %s password for %s from keyring" % (domain, user))
except subprocess.CalledProcessError:
print(
"Unable to set password using `keyring` (is it in your PATH?) — expect to be nagged",
file=sys.stderr,
)
return {"user": user, "password": password}
connect_kwargs = get_config()
¿Existe / planea haber una forma más limpia de hacer esto? Entre otras cosas, este código no es del todo equivalente a la versión de Fabric 1 porque no extrae el nombre de usuario de la configuración, lo cual no es algo que necesite, pero parece que debería haber una forma de decir "Obtenga el procesamiento config y actualice este valor ”.
Tenía la intención de que los archivos de configuración de "formato Python" llenarían aproximadamente el vacío de "rellenar los valores de configuración mediante la ejecución del código en tiempo de ejecución", por lo que podría decirse que estaba en el camino correcto con el archivo .py
. Dicho esto, no seguí ese pensamiento hasta la conclusión y parece que estás pagando por eso, disculpas. (Notaré que parte de la razón es que asumí que la mayoría de los usuarios avanzados estarían haciendo cosas en su archivo de tareas / fabfile, pero de cualquier manera, el puente entre los datos config-esque y los cuerpos de tareas en tiempo de ejecución necesita funcionar).
No recuerdo de improviso qué serían las cosas decapadas, pero probablemente sea una peculiaridad del sistema de configuración, tendré que profundizar en eso. No me gusta el pepinillo (en estos días, a quién le gusta), así que fue un poco sorprendente encontrarlo aparecer en este contexto.
Independientemente, la causa próxima es que asumimos que el contenido del módulo "es" la configuración, por lo que necesitamos un filtrado más estricto cuando pasamos de los atributos del objeto del módulo al dict anidado de la configuración. Honestamente, eliminar módulos podría ser todo lo que se necesita, ya que cualquier otra asignación de variable podría ser un mal comportamiento por parte del autor del archivo de configuración.
Re: la pregunta de diseño de nivel superior de "mutar solo un valor de configuración anidado", que _ debería_ funcionar intuitivamente en la mayoría de los casos (el proceso de combinación de configuraciones tiende a hacer una combinación profunda, por lo que su archivo .py simplemente configura connect_kwargs = {'user': foo', 'password': 'bar'}
debería terminar combinado con el contenido connect_kwargs
cualquier otra fuente de configuración) pero creo que podría haber algunos errores alrededor de connect_kwargs
específicamente, por ejemplo, # 1762.
Debería volver a probar esto ya que ese fue mi intento inicial de actualización de Fabric 2 y he visto muchas confirmaciones volando desde entonces.
¿Existe un ejemplo simple de hola mundo usando un archivo fabfile.py? He estado leyendo todos los documentos y buscando en Internet durante un par de días y todavía no he podido ejecutar un solo comando de forma remota en la v2. Por lo que sé, está atascado con una SSHException "No hay métodos de autenticación disponibles"
Comentario más útil
¿Existe un ejemplo simple de hola mundo usando un archivo fabfile.py? He estado leyendo todos los documentos y buscando en Internet durante un par de días y todavía no he podido ejecutar un solo comando de forma remota en la v2. Por lo que sé, está atascado con una SSHException "No hay métodos de autenticación disponibles"