Fabric: Ganchos de ejecución remota de Python

Creado en 19 ago. 2011  ·  28Comentarios  ·  Fuente: fabric/fabric

Descripción

Solo un marcador de posición que eventualmente, si las personas necesitan la función y es lo suficientemente fácil de integrar/tiene sentido integrar en lugar de simplemente decir "hágalo usted mismo, es solo Python", deberíamos considerar facilitar el uso de herramientas para la ejecución remota de Python /RPC. Los candidatos útiles en la actualidad incluyen:

  • ejecutivo

    • desarrollado activamente pero solo puede admitir Python hasta 3.4?

    • el transporte es popen (local), ssh (a través de binario 😒) o socket directo (con bootstrappy script remoto/servidor en el repositorio)

    • la serialización es completamente manual, usando struct

    • se usa para pytest distribuido, por lo que es al menos algo probado en batalla

    • API relativamente sensata (objetos de puerta de enlace y canal, enviar/recibir, asíncrono ligero disponible) si carece de documentos API explícitos de estilo moderno (¿parece ser SOLO un ejemplo/prosa?)

  • piro(4)

    • desarrollado activamente, parece admitir al menos hasta 3.6 si no también 3.7

    • serializa con una biblioteca independiente basada en AST llamada serpent (que establece explícitamente en su LÉAME por qué existe y por qué Pyro no usa XML, JSON, Pickle, etc.)

    • transporta con TCP/IP, sockets Unix y, opcionalmente, puede usar SSL/TLS

    • extremadamente funcional, que incluye cosas como generar excepciones remotas en el extremo de la persona que llama, manejar las reconexiones automáticamente, etc.

    • Buena API limpia (comprensiblemente, a un alto nivel, similar a los objetos re: de execnet que representan al intérprete remoto, aunque un poco más moderno) que incluye la opción de usar decoradores para declarar llamadas RPC

  • mitógeno

    • desarrollado activamente (el mantenedor está en los comentarios a continuación), admite hasta Python 3.6 al menos

    • serializa con pickle , desafortunadamente, aunque hay una razón

    • transporte: en realidad no es 100% seguro, pero se siente como conexiones de socket directas combinadas con cada hijo de Mitogen capaz de enrutar solicitudes hacia adelante en una topología.

    • Relativamente funcional y las características que tiene suenan muy poderosas

    • puede ejecutarse incluso si el extremo remoto no tiene espacio libre en disco, etc. - ¡genial!

    • Reenvío de módulo del lado de la persona que llama de lujo; no estoy seguro si/cómo las otras opciones incluso manejan las importaciones que no son stdlib.

    • las llamadas del módulo de registro de extremo remoto se reenvían automáticamente a la persona que llama

    • Menos inmediatamente relevante para el caso de uso Fab promedio de nodo único/lista de nodos hermanos: algunos énfasis muy claros en árboles de procesos secundarios, árboles sin cabeza y otras estrategias de topología

    • Arranca automáticamente siempre que el extremo remoto tenga SSH y Python, y no requiera transferir un archivo primero (en comparación con, por ejemplo, execnet que requiere el uso de un script remoto)

    • API algo más compleja que, por ejemplo, Pyro/execnet (alrededor de 1 capa más de objetos) pero no necesariamente de mala manera dadas sus características/diseño adicionales

  • Lado del kernel de IPython

    • mantenido activamente (¡alguna vez!)

    • usa ZMQ para el transporte entre algún cliente y un proceso del kernel jupyter/ipython

    • serializa con JSON, alternativamente msgpack/pickle

Opciones que pueden no ser factibles pero vale la pena rastrear:

  • Agresivo (el enlace va a la entrada del blog que analiza específicamente la integración de Fabric con él) _- sin soporte/archivado desde 2016, aunque según se indica a continuación, el autor expresó anteriormente su interés en colaborar_
  • Salt _- Posibilidad remota (juego de palabras no intencionado) de que uno podría intentar reutilizar los bits de ejecución remota controlados por ZMQ de salt, pero a simple vista no parecen ser factorizados de manera reutilizable ni nada.
  • Celery _- similar a salt re: arco de paso de mensaje/sub/pub de alto nivel y necesita intentar extraer un flujo de nivel inferior, excepto que requiere un sistema de cola/intermediario (frente a ZMQ que puede hacer conexiones directas de estilo socket a socket) por lo que incluso menos factible?_
  • etc. (lista de proyectos de Python wiki) _- escaneado por última vez a principios de 2019, todos los candidatos útiles obvios ya se retiraron_

De antemano, creo que el atractivo principal sería conectar la configuración de host/usuario/etc. de Fabric a dicha herramienta. Entonces, probablemente algo más en la línea de nuestra contribución de Django, en lugar de una integración central (especialmente porque muchos usuarios pueden no tener Python de forma remota, por lo que absolutamente no querríamos _requerir_ el uso de dicha herramienta).


El autor de Pushy también menciona la posibilidad de usar su herramienta en Fabric como una capa potencial sobre Paramiko; Supongo que el mismo enfoque podría aplicarse a las otras herramientas también.

No estoy del todo seguro de si ese sería un buen camino a seguir; plus es un eventual desacoplamiento de SSH específicamente; el inconveniente es que, bueno, somos bastante específicos de SSH en muchos sentidos (y usamos muchas cosas básicas de Paramiko) y no estoy seguro de que valga la pena perder el enfoque.


Enviado originalmente por Jeff Forcier ( bitprophet ) el 2010-09-20 a las 11:43 am EDT

Relaciones

  • Duplicado por # 246: capacidad para ejecutar fácilmente de forma remota pequeños fragmentos de Python (en lugar de comandos de shell)
Core Feature Needs investigation Network

Todos 28 comentarios

Seán Hayes (Sean_Hayes) publicó:


Creé una bifurcación en GitHub: https://github.com/SeanHayes/fabric

En fabric.decorators agregué un decorador llamado runs_on_remote. Es una especie de ejecución remota de un hombre pobre.

Básicamente, cuando envuelve una función con él, si env.hosts no está vacío, el decorador ejecutará 'fab func_name' en el host en lugar de permitir que la función se ejecute localmente. Por ejemplo:

from fabric.api import *

env.hosts = []

def remote():
    env.hosts = ['your_host']

@runs_on_remote(remote_fabfile_path='/path/to/fabfile/dir/')
def foo():
    print local('ls /')

Ejecutar 'fab remote foo' localmente hará que 'fab foo' se ejecute en 'your_host'.


el 2011-01-16 a las 08:27 p.m. EST

Más avances en esto. Después de usar tela por un tiempo, veo esto como una de las grandes piezas que faltan. Ser capaz de escribir métodos de utilidad remotos en Python puro sin duda podría facilitar la escritura de tareas remotas.

No hay comentarios == no hay progreso, lo siento :) Este no es un gran obstáculo para la mayoría de los usuarios -- la mayoría se siente básicamente cómoda con las secuencias de comandos de shell. Entonces, si bien esto está _definitivamente_ cerca de la parte superior de la lista "agradable de tener", todavía está en la lista de "agradable de tener".

Espero que se vea más de cerca cuando comencemos a organizar la versión 2.x (en algún momento de los próximos meses, si no antes), ya que es un buen momento para hacer que "hacer X en la ubicación Y" sea una operación más abstracta.

Una simplificación que puede valer la pena considerar es simplemente hacer posible ejecutar un script de python temporal en el sistema remoto. Incluso había considerado una forma manual de hacer esto creando un archivo 'remote_utils.py' o algo que puse en el sistema remoto al inicio y luego llamé a ese script con el nombre de la función que quiero ejecutar dentro del módulo.

Suponiendo que te refieres a alguna forma de "copiar .py local en el sistema remoto, ejecutarlo, luego probablemente eliminarlo de nuevo", sí, eso también se patea ocasionalmente. (Vea algunos de los comentarios anteriores, incluso).

Pero eso no requiere soporte central, por lo que probablemente pertenecería a la biblioteca de código local de uno o, por ejemplo, a Patchwork .

Solo me gustaría señalar que ya hay una biblioteca, bifurcada de 'sshuttle', que implementa esto:

Remote Exec le permite enviar código Python a una máquina remota y ejecutarlo allí, todo sin instalar nada más que el intérprete estándar de Python en el servidor.

Se conecta al host remoto mediante SSH, envía los archivos de Python que especifique, los compila en el servidor y pasa el control a la función principal especificada.

Además, el cliente hace arreglos para que stdin/stdout en el lado del servidor se conecte a un socket de red en el lado del cliente, para que pueda comunicarse con el servidor binario cargado como si se hubiera conectado a él normalmente.

https://bitbucket.org/danderson/py-remoteexec

Dicho esto, el código original (y por lo tanto, la bifurcación también) tiene licencia GPLv2, y no estoy seguro de si los autores están dispuestos a volver a obtener la licencia.

@bitprophet Estaba pensando lo mismo que esto podría ser un módulo de extensión local. Simplemente no he encontrado una buena implementación que pueda copiar y refinar. Si alguien sabe de uno, me encantaría verlo y probarlo.

@abierbaum Verifique las bibliotecas enumeradas en el n. ° 461, apuesto a que al menos una de ellas puede tener alguna implementación de esto.

La implementación de fantasía solo tendría un decorador @remote en cualquier función de python y cuando se llama, la función real se ejecuta en el objetivo remoto. De las librerías señaladas, execnet parece la mejor, pero también la más compleja. (Simplemente saltando a través de la documentación).

Los diversos enfoques de "colocar el código en el servidor y ejecutarlo" no parecen agregar mucho valor en lugar de simplemente "colocar" el archivo, sudo ejecutarlo y eliminarlo. Sin mencionar que este método le permite ejecutar cualquier código, no solo el código de Python.

Esto es algo que sería realmente útil para mí si funcionara bien. Por ejemplo, me encantaría usar algo como _psutils_ para manipular procesos en lugar de los métodos ps > grep > awk > kill que tengo que usar ahora.

Si alguien quisiera implementar esto, ¿qué método sería más probable que usara en la contribución?

¿Por qué no solo

print run("""python -c 'import re
m = re.search("1", "m1m")
print m'""")
[localhost] run: python -c 'import re
m = re.search("1", "sfsdf1231231231dfads")
print m'
[localhost] out: <_sre.SRE_Match object at 0x1086cd8b8>

De hecho, agregué la solución alternativa (poner, ejecutar, eliminar) a Patchwork hace poco tiempo, https://github.com/fabric/patchwork/blob/master/patchwork/commands.py#L11 - es un primer borrador, por lo que podría usar un poco de amor en algún momento estoy seguro.

Esto hace el trabajo si sus funciones son independientes, por lo tanto, debe importar en el cuerpo de la función.

def rpc(f):
    @wraps(f)
    def wrapper(*l, **kw):
        c = 'python -c "import marshal,pickle,types;types.FunctionType(marshal.loads(%r),globals(),%r)(*pickle.loads(%r),**pickle.loads(%r))"'
        c = c % (marshal.dumps(f.func_code),f.func_name,pickle.dumps(l),pickle.dumps(kw))
        run(c)
    return wrapper

Ejemplo:

<strong i="9">@task</strong>
<strong i="10">@rpc</strong>
def f(): print 1+1

Funciona bien, pero fabric falla al serializar funciones largas en su mecanismo de escape bash.
El diseño de fabric es totalmente defectuoso porque su api, run(string) implica escapar.
La api correcta de ejecutar debe ejecutarse (cmd = []) donde cmd es una lista.
Fabric no debe escaparse, pero debe usarse serialize y execv en lugar de exec /bin/sh -c string.
run(string) podría admitirse, pero se debe desaconsejar su uso.

Si ssh no es compatible con execv char *const argv[], entonces se debe usar un pequeño ayudante en el lado remoto, podríamos hacer este ayudante en python o en perl. Este ayudante también podría admitir python rpc como el ejemplo anterior

Así que probé lo que @antonylesuisse sugirió anteriormente, pero me encontré con algunos problemas. Por alguna razón, no podía importar módulos directamente, e incluso si los importaba en el lado remoto con un ejecutivo tan pronto como intentaba acceder a ellos, el intérprete fallaba en el segmento. Parece que eso puede deberse a que ejecuto diferentes versiones de python, y la versión de python realmente ejecuta fabric en un entorno de miniconda.

Aquí hay algunas funciones que colocan el código fuente, lo ejecutan después de decapar/quitar los argumentos, luego obtienen la respuesta decapada directamente desde el archivo de salida. Creo que esto debería evitar cualquier problema de escape de shell... por supuesto, las respuestas aún tienen que ser pickleable/no pickleable pero mientras lo sean, parece funcionar bien.

Se adjunta un script de ejemplo.
rpc_ejemplo.py.zip
.
Esto todavía no es interactivo, pero al menos puede ejecutar código no interactivo con él. ¿Alguien se ha sumergido en la integración de execnet o Pushy?

@raddessi Parece que Chopsticks podría ser la biblioteca que está buscando.

usé tela como palillos. y creo que es mucho más simple.
Viernes, 18 de agosto de 2017 14:23:20 +0000 (UTC)
Fabien Meghazi [email protected]已寫入:

@raddessi Parece que
Los palillos pueden ser el
biblioteca que busca.

https://mitogen.readthedocs.io/en/latest/ es un recién llegado a la escena aquí y aunque ya no recuerdo cómo funcionan exactamente los otros enumerados anteriormente, este literalmente inicia un intérprete de Python remoto en memoria ( no requiere Python instalado de forma remota; usa SSH, pero no Paramiko, sollozo) y empuja el código para su ejecución.

Aparentemente, también puede obligar a los subprocesos a usar el proceso local para SSH, lo que le permite hacer cosas como SFTP-over-sudo (no entiendo cómo funciona eso, pero aún no he leído la fuente).

Sin embargo, no es compatible con Python 3 y afirma no tener planes allí, por lo que podría ser un bloqueador ya que Fabric 2 / Invoke son explícitamente compatibles con 2+3.

@bitprophet "Mitogen es una biblioteca de Python para escribir programas de autorreplicación distribuidos". ¿Esto realmente encaja? ¿Por qué no Ansible? ¿Has mirado en Ansible? Tengo curiosidad por lo que piensas. Cambiamos de tela a sal, pero no estoy 100% feliz con eso. Supongo que usaría Ansible la próxima vez.

Examiné Salt y Ansible hace un tiempo y tampoco me gustaron mucho. Dicho esto, considero que Fabric es en su mayoría ortogonal a los sistemas de administración de configuración 'completos' como esos, por lo que no es realmente una comparación justa. (Puede obtener, digamos, el 75-85% del camino con Fabric, muchas personas lo hacen, y me gustaría mejorar eso donde podamos, pero Fabric siempre será más una biblioteca de tipo de bloque de construcción de abajo hacia arriba mientras que la mayoría de las herramientas de CM como Salt/Ansible/Chef/Puppet son más como marcos de arriba hacia abajo).

@bitprophet gracias por tu respuesta.

No estoy contento con la sal, no estoy contento con la tela.

Fabric es a veces como "ejecución remota de shell". Cambié de scripts de shell a python hace varios años porque me encantan los rastreos y las excepciones. La ejecución tipo Shell (en caso de error, escribir en stdout/stderr y continuar con la siguiente línea) no es aceptable en mi contexto. Prefiero las excepciones no detectadas a "continuar por error", especialmente en los sistemas de producción.

La tela se sintió como un paso atrás.

Lo usamos algunas veces, pero cambiamos a sal.

Pero Salt es demasiado complicado.

En mi equipo, la mayoría de los desarrolladores hacen una gran reverencia en torno a la sal.

Eso era diferente con la tela.

Estoy sentado entre las sillas.

No he probado Ansible hasta ahora. Pero parece más sencillo y eso es importante para mí.

Espero que las siguientes palabras no le hagan daño. ... Creo que no volveré a cambiar a la tela.

Para mí, creo que el tejido es una herramienta de ejecución remota. SaltStack/Ansible/Puppet/Chef son una especie de plataforma de gestión estatal. El objetivo es diferente.
Fabric proporciona una forma sencilla de administrar el host remoto. Hay algunas bibliotecas que ofrecen un lote de fragmentos de código para Fabric. Es una dirección de "Gestión del Estado".
Si queremos que Fabric resuelva un problema de ejecución remota más sofisticado, pide a los usuarios que escriban sus componentes para manejar la conexión u otro personal. Mitogen se adapta a este caso.

La ejecución tipo Shell (en caso de error, escribir en stdout/stderr y continuar con la siguiente línea) no es aceptable en mi contexto. Prefiero las excepciones no detectadas a "continuar por error", especialmente en los sistemas de producción.

Para ser justos, Fabric no debería continuar con un error, por lo que si está viendo eso, algo más está sucediendo.

Dicho esto, todavía no es tan limpio en cuanto a excepciones como nos gustaría (básicamente, todos los errores dan como resultado SystemExit) y la versión 2 se está construyendo para ser mucho más amigable con las excepciones (con SystemExit solo levantado en los bordes exteriores del programa.)

Hola @bitprophet , solo para señalar que el soporte de Python 3 para Mitogen es un objetivo más explícito en estos días. No debería requerir más de un par de semanas para llegar, y es necesario de todos modos para admitir Ansible en las próximas versiones de Fedora.

Hola @bitprophet , otra nota para decir que Python 3 hace mucho (mucho tiempo) que llegó al maestro por última vez, y el resultado estará en PyPI como el primer lanzamiento estable de la serie mañana por la noche. El soporte 'fakessh' actualmente está roto y no está dentro del alcance, pero me muero por atascarme en arreglarlo y generalizarlo para el reenvío de TCP/UDP/tubería, con la esperanza de que después de dejar atrás este estancamiento de Python 3, la energía regrese. y muchas cosas nuevas sucederán muy rápido ahora :)

Impresionante, me alegra escucharlo @dw! No sé cuándo tendré tiempo de ver la integración de Mitogen por mi parte, pero estoy muy contento de que la barrera de la versión del intérprete ya no exista 👍

@bitprophet ¿ alguna actualización sobre esto?

@bitprophet esta característica es muy útil para nuestro propósito (depuración remota), me encantaría ayudar en la implementación de cualquier manera posible.

Me acabo de enterar de mitógeno, y creo que sería un excelente backend para la tela.

de hecho, creo que podría reemplazar ventajosamente una gran cantidad de código de estructura (y posiblemente también la mayor parte de pyinvoke). elimina la distinción de "caso especial" entre fabric/invoke (ssh/local) y fusiona todo esto en un "contexto" mágico que también funciona en backends como "sudo" de forma más transparente que fabric (en mi humilde opinión).

ahora mismo realmente siento el dolor de esta característica que falta en la tela. Estoy buscando implementar una lógica comercial cada vez más compleja en el extremo remoto. en este momento, esto implica transferir archivos de un lado a otro con sftp para asegurarse de que las cosas estén configuradas correctamente, y es un poco torpe. Sería mucho mejor hacerlo de forma remota: abrir el archivo, buscar contenido, buscar/reemplazar, etc., se vuelve mucho más intuitivo.

también hace posible escribir código Python que sea reutilizable fuera de la estructura. en este momento realmente no puedo hacer eso, a menos que entrecierre los ojos, porque fundamentalmente, el código de python solo se ejecuta localmente. así que necesito copiar archivos (¿o procesos?) de un lado a otro entre hosts para hacer lo que necesito. está lejos de ser ideal...

ahora mismo estoy en un cruce: o sigo por la ruta de la estructura, o simplemente transfiero todo mi código a mitógeno y hago un pequeño envoltorio de ejecutor a su alrededor... no uso la función fabfile lo suficiente para garantizar la complejidad de la estructura, mientras que Mitogen me brinda funciones mucho más potentes para mi caso de uso principal (que es arrancar y recuperar servidores de entornos heterogéneos)...

pero entiendo que también hay otros casos de uso para fabric e invocar, por supuesto. Siento que sería mucho más natural escribir código Python nativo, incluso para la funcionalidad existente en Fabric (como la ejecución de código), porque haría que el manejo de errores, el control de tuberías y los reflejos existentes funcionaran más o menos normalmente...

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

bitprophet picture bitprophet  ·  6Comentarios

jmcgrath207 picture jmcgrath207  ·  5Comentarios

yuvadm picture yuvadm  ·  5Comentarios

acdha picture acdha  ·  4Comentarios

omzev picture omzev  ·  6Comentarios