Fabric: Remote-Python-Ausführungs-Hooks

Erstellt am 19. Aug. 2011  ·  28Kommentare  ·  Quelle: fabric/fabric

Beschreibung

Nur ein Platzhalter, der schließlich, wenn Leute das Feature brauchen und es einfach genug zu integrieren / sinnvoll ist, zu integrieren, anstatt nur zu sagen "mach es selbst, es ist nur Python" - wir in Betracht ziehen sollten, es einfach zu machen, Tools für die Remote-Python-Ausführung zu nutzen /RPC. Zu den modernen nützlichen Kandidaten gehören:

  • ausführen

    • aktiv entwickelt, unterstützt aber möglicherweise nur Python bis 3.4?

    • Transport ist popen (lokal), ssh (über binär 😒) oder direkter Socket (mit Bootstrappy-Remote-Skript/Server-In-Repo)

    • Die Serialisierung erfolgt vollständig per Handrolling unter Verwendung struct

    • Wird für verteilte Pytest verwendet und ist daher zumindest etwas kampferprobt

    • API relativ vernünftig (Gateway- und Kanalobjekte, Senden/Empfangen, leichte Asynchronität verfügbar), wenn explizite API-Dokumente im modernen Stil fehlen (scheint NUR beispiel-/prosagesteuert zu sein?)

  • Pyro(4)

    • aktiv entwickelt, scheint mindestens bis 3.6 zu unterstützen, wenn nicht auch 3.7

    • serialisiert mit einer AST-basierten eigenständigen Bibliothek namens serpent (die in ihrer README explizit angibt, warum sie existiert und warum Pyro kein XML, JSON, Pickle usw. verwendet)

    • transportiert mit TCP/IP, Unix-Sockets und kann optional SSL/TLS verwenden

    • extrem funktionsreich, einschließlich Dinge wie das Auslösen von Remote-Ausnahmen auf der Seite des Anrufers, das automatische Behandeln von Wiederverbindungen usw

    • schöne saubere API (verständlicherweise auf hohem Niveau, ähnlich wie bei execnet: Objekte, die den Remote-Interpreter darstellen, wenn auch etwas moderner) einschließlich der Option, Dekoratoren zu verwenden, um RPC-Aufrufe zu deklarieren

  • Mitogen

    • aktiv entwickelt (Maintainer ist in den Kommentaren unten), unterstützt mindestens bis zu Python 3.6

    • serialisiert w/ pickle , leider, obwohl es eine Begründung gibt

    • Transport: Eigentlich nicht 100% sicher, aber fühlt sich an wie direkte Socket-Verbindungen in Kombination mit jedem Mitogen-Kind, das in der Lage ist, Anfragen in einer Topologie weiterzuleiten?

    • Relativ funktionsreich und die Funktionen, die es hat, klingen alle sehr kraftvoll

    • läuft auch wenn die Gegenstelle keinen freien Speicherplatz hat etc - ordentlich!

    • Schicke anruferseitige Modulweiterleitung; Ich bin mir nicht sicher, ob/wie die anderen Optionen überhaupt nicht-stdlib-Importe handhaben.

    • Remote-End-Logging-Modul-Anrufe werden automatisch an den Anrufer zurückgeleitet

    • weniger unmittelbar relevant für den durchschnittlichen Fab-Anwendungsfall mit Einzelknoten/Liste von Geschwisterknoten: einige sehr ordentliche Betonungen auf Bäumen von untergeordneten Prozessen, kopflosen Bäumen und anderen Topologiestrategien

    • Bootstraps automatisch, solange das entfernte Ende über SSH und Python verfügt, und es muss nicht zuerst eine Datei übertragen werden (im Vergleich zu z. B. execnet, das die Verwendung eines entfernten Skripts erfordert)

    • API etwas komplexer als zB Pyro/execnet (ca. 1 weitere Ebene von Objekten), aber nicht unbedingt auf eine schlechte Art und Weise angesichts seiner zusätzlichen Funktionen/Layout

  • Die Kernel-Seite von IPython

    • aktiv gewartet (gibt es das jemals!)

    • verwendet ZMQ für den Transport zwischen einem Client und einem Jupyter/Ipython-Kernel-Prozess

    • serialisiert mit JSON, alternativ msgpack/pickle

Optionen, die möglicherweise nicht machbar sind, aber es wert sind, verfolgt zu werden:

  • Aufdringlich (Link führt zu Blogeintrag, in dem speziell die Integration von Fabric damit diskutiert wird) _- seit 2016 nicht mehr unterstützt/archiviert, obwohl der Autor gemäß unten früher Interesse an einer Zusammenarbeit bekundet hat_
  • Salt _- Remote (Wortspiel nicht beabsichtigt) Möglichkeit, dass man versuchen könnte, die ZMQ-gesteuerten Remote-Ausführungsbits von Salt wiederzuverwenden, aber auf einen sehr schnellen Blick scheinen sie nicht auf wiederverwendbare Weise oder irgendetwas faktorisiert zu sein_
  • Sellerie _- ähnlich wie Salt re: High-Level-Pub/Sub/Message-Passing-Bogen und muss versuchen, einen Low-Level-Fluss zu extrahieren, außer dass ein Broker-/Warteschlangensystem erforderlich ist (im Gegensatz zu ZMQ, das direkte Socket-to-Socket-Verbindungen herstellen kann), also sogar weniger machbar?_
  • etc (Python-Wiki-Liste der Projekte) _- zuletzt Anfang 2019 gescannt, alle offensichtlich nützlichen Kandidaten bereits herausgezogen_

Nebenbei denke ich, dass die Hauptattraktion darin bestehen würde, Ihre Fabric-Host-/Benutzer-/usw.-Einstellungen in ein solches Tool einzubinden. Also eher etwas in der Art unseres Django-Beitrags anstelle einer Core-Integration (insbesondere, da viele Benutzer Python möglicherweise nicht aus der Ferne haben, sodass wir die Verwendung eines solchen Tools absolut nicht _erfordern_ möchten).


Der Autor von Pushy erwähnt auch die Möglichkeit, sein Werkzeug in Fabric als mögliche Schicht auf Paramiko zu verwenden; Ich denke, der gleiche Ansatz könnte auch auf die anderen Tools angewendet werden.

Nicht ganz sicher, ob das ein guter Weg wäre; plus ist eine eventuelle Entkopplung von SSH speziell; Minuspunkt ist, dass wir in vielerlei Hinsicht ziemlich SSH-spezifisch sind (und viel Kern-Paramiko-Zeug verwenden) und ich bin mir nicht sicher, ob es den Fokusverlust wert wäre.


Ursprünglich eingereicht von Jeff Forcier ( bitprophet ) am 20.09.2010 um 11:43 Uhr EDT

Beziehungen

  • Dupliziert durch #246: Möglichkeit, kleine Python-Snippets (anstelle von Shell-Befehlen) einfach aus der Ferne auszuführen
Core Feature Needs investigation Network

Alle 28 Kommentare

Seán Hayes (Sean_Hayes) schrieb:


Ich habe einen Fork auf GitHub erstellt: https://github.com/SeanHayes/fabric

In fabric.decorators habe ich einen Decorator namens runnings_on_remote hinzugefügt. Es ist eine Art Fernhinrichtung eines armen Mannes.

Wenn Sie eine Funktion damit umschließen und env.hosts nicht leer ist, führt der Decorator grundsätzlich „fab func_name“ auf dem Host aus, anstatt zuzulassen, dass die Funktion lokal ausgeführt wird. Zum Beispiel:

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 /')

Wenn Sie „fab remote foo“ lokal ausführen, wird „fab foo“ auf „your_host“ ausgeführt.


am 16.01.2011 um 20:27 Uhr EST

Weitere Fortschritte diesbezüglich. Nachdem ich eine Weile Stoff verwendet habe, sehe ich dies als eines der großen fehlenden Teile. In der Lage zu sein, Remote-Utility-Methoden in reinem Python zu schreiben, könnte es sicherlich einfacher machen, Remote-Tasks zu schreiben.

Keine Kommentare == kein Fortschritt, Entschuldigung :) Dies ist für die meisten Benutzer kein großer Blocker - die Mehrheit ist im Grunde mit Shell-Scripting vertraut. Während dies also _definitiv_ ganz oben auf der „nice to have“-Liste steht, ist es immer noch in der „nice to have“-Liste.

Ich gehe davon aus, dass es genauer betrachtet wird, wenn wir uns mit der Organisation von Version 2.x befassen (irgendwann in den nächsten Monaten, wenn nicht früher), da dies eine großartige Zeit ist, um „X an Standort Y ausführen“ zu einer abstrakteren Operation zu machen.

Eine Vereinfachung, die eine Überlegung wert sein könnte, besteht darin, es einfach zu ermöglichen, ein temporäres Python-Skript auf dem Remote-System auszuführen. Ich hatte sogar über eine manuelle Möglichkeit nachgedacht, dies zu tun, indem ich eine Datei „remote_utils.py“ oder etwas anderes erstellte, das ich beim Start auf dem Remote-System ablegte, und dann dieses Skript mit dem Namen der Funktion aufrief, die ich innerhalb des Moduls ausführen möchte.

Angenommen, Sie meinen eine Form von "lokales .py auf Remote-System kopieren, ausführen, dann wahrscheinlich wieder entfernen", ja, das wird auch gelegentlich herumgeschmissen. (Siehe sogar einige der Kommentare oben.)

Aber das erfordert keine Core-Unterstützung, also würde es wahrscheinlich in die eigene lokale Code-Bibliothek oder zB in Patchwork gehören.

Ich möchte nur darauf hinweisen, dass es bereits eine von 'sshuttle' geforkte Bibliothek gibt, die dies implementiert:

Mit Remote Exec können Sie Python-Code an einen Remote-Computer senden und dort ausführen, ohne etwas anderes als den Standard-Python-Interpreter auf dem Server zu installieren.

Es stellt über SSH eine Verbindung zum Remote-Host her, sendet die von Ihnen angegebenen Python-Dateien, kompiliert sie auf dem Server und übergibt die Steuerung an die angegebene Hauptfunktion.

Darüber hinaus sorgt der Client dafür, dass stdin/stdout auf der Serverseite mit einem Netzwerk-Socket auf der Clientseite verbunden wird, sodass Sie mit der hochgeladenen Server-Binärdatei so kommunizieren können, als ob Sie sich normal damit verbunden hätten.

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

Allerdings ist der Originalcode (und damit auch der Fork) GPLv2-lizenziert, und ich bin mir nicht sicher, ob die Autoren bereit sind, ihn erneut zu lizenzieren.

@bitprophet Ich dachte dasselbe, dass dies ein lokales Erweiterungsmodul sein könnte. Ich habe einfach keine gute Implementierung davon gefunden, die ich kopieren und verfeinern könnte. Wenn jemand einen kennt, würde ich ihn gerne sehen und ausprobieren.

@abierbaum Überprüfen Sie die in # 461 aufgeführten Bibliotheken. Ich wette, mindestens eine von ihnen hat möglicherweise eine Implementierung davon.

Die Fantasieimplementierung hätte nur einen @remote- Dekorator für jede Python-Funktion, und wenn sie aufgerufen wird, wird die eigentliche Funktion auf dem entfernten Ziel ausgeführt. Von den aufgezeigten Bibliotheken scheint execnet die beste beste, aber auch die komplexeste zu sein. (Überspringen Sie einfach die Dokumentation).

Die verschiedenen Ansätze "Code auf dem Server ablegen und ausführen" scheinen keinen großen Mehrwert zu bieten, als nur ein "Ablegen" der Datei durchzuführen, sie mit sudo auszuführen und sie zu löschen. Ganz zu schweigen davon, dass Sie mit dieser Methode jeden Code ausführen können, nicht nur Python-Code.

Das wäre etwas, was mir sehr helfen würde, wenn es gut funktionieren würde. zB würde ich gerne so etwas wie _psutils_ verwenden, um Prozesse zu manipulieren, anstatt die Methoden ps > grep > awk > kill, die ich jetzt verwenden muss.

Wenn jemand dies implementieren möchte, welche Methode würden Sie am ehesten in den Beitrag ziehen?

Warum nicht einfach

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>

Ich habe die Problemumgehung (put, run, remove) vor Kurzem tatsächlich zu Patchwork hinzugefügt, https://github.com/fabric/patchwork/blob/master/patchwork/commands.py#L11 - es ist ein erster Entwurf, der verwendet werden könnte etwas Liebe irgendwann, da bin ich mir sicher.

Dies erledigt die Aufgabe, wenn Ihre Funktionen eigenständig sind, daher müssen Sie den Funktionskörper importieren.

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

Beispiel:

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

Funktioniert gut, aber Fabric schlägt fehl, wenn lange Funktionen in seinem Bash-Escape-Mechanismus serialisiert werden.
Das Design des Stoffes ist völlig fehlerhaft, da sein api, run(string) das Entkommen impliziert.
Die korrekte API von run sollte run(cmd=[]) sein, wobei cmd eine Liste ist.
Fabric sollte nicht maskiert werden, aber serialize und execv muss anstelle von exec /bin/sh -c string verwendet werden.
run(string) könnte unterstützt werden, aber von seiner Verwendung sollte abgeraten werden.

Wenn ssh execv char *const argv[] nicht unterstützt, dann sollte ein kleiner Helfer auf der entfernten Seite verwendet werden, wir könnten diesen Helfer in Python oder in Perl machen. Dieser Helfer könnte auch Python-RPC wie im obigen Beispiel unterstützen

Also habe ich versucht, was @antonylesuisse oben vorgeschlagen hat, bin aber auf einige Probleme gestoßen. Aus irgendeinem Grund konnte ich Module nicht direkt importieren, und selbst wenn ich sie auf der Remote-Seite mit einem Exec importierte, sobald ich versuchte, auf sie zuzugreifen, würde der Interpreter segfault. Es sieht so aus, als ob das daran liegen könnte, dass ich verschiedene Versionen von Python ausführe, wobei die Version von Python, in der Fabric tatsächlich ausgeführt wird, sich in einer Miniconda-Umgebung befindet.

Hier sind einige Funktionen, die den Quellcode einfügen, ihn nach dem Picken/Unpicken der Argumente ausführen und dann die eingelegte Antwort direkt aus der Ausgabedatei über die Leitung zurückerhalten. Ich denke, dies sollte Probleme mit Shell-Escapes vermeiden. Natürlich müssen die Antworten immer noch pickleable / unpickleable sein, aber solange sie es sind, scheint es in Ordnung zu funktionieren.

Ein Beispielskript ist beigefügt.
rpc_example.py.zip
.
Dies ist immer noch nicht interaktiv, aber Sie können zumindest nicht interaktiven Code damit ausführen. Hat sich jemand mit der execnet- oder Pushy-Integration beschäftigt?

@raddessi Es scheint, dass Chopsticks die Bibliothek sein könnten, nach der Sie suchen.

Ich habe Stoff wie Essstäbchen verwendet. und ich denke, es ist viel einfacher.
am Fr, 18. Aug. 2017 14:23:20 +0000 (UTC)
Fabien Meghazi [email protected]已寫入:

@raddessi Es scheint so
Essstäbchen könnten das sein
Bibliothek, die Sie suchen.

https://mitogen.readthedocs.io/en/latest/ ist hier ein Neuling in der Szene, und obwohl ich mich nicht mehr daran erinnere, wie genau die anderen oben aufgeführten funktionieren, bootet dieser hier buchstäblich einen Remote-Python-Interpreter im Speicher ( erfordert keine Remote-Installation von Python, verwendet SSH - aber nicht Paramiko, sob) und schiebt Code zur Ausführung hinein.

Es kann anscheinend auch Unterprozesse dazu zwingen, den lokalen Prozess für SSH zu verwenden, wodurch Dinge wie SFTP-over-Sudo ausgeführt werden können (ich verstehe nicht ganz, wie das funktioniert, habe aber die Quelle noch nicht gelesen.)

Es ist jedoch nicht Python 3-kompatibel und behauptet, dort keine Pläne zu haben, könnte also ein Blocker sein, da Fabric 2 / Invoke explizit 2 + 3-kompatibel sind.

@bitprophet "Mitogen ist eine Python-Bibliothek zum Schreiben von verteilten selbstreplizierenden Programmen." Passt das wirklich. Warum nicht Ansible? Hast du dir Ansible angeschaut? Ich bin gespannt, was Sie denken. Wir sind von Stoff auf Salz umgestiegen, aber ich bin nicht 100% zufrieden damit. Ich denke, ich würde das nächste Mal Ansible verwenden.

Ich habe vor einiger Zeit sowohl Salt als auch Ansible untersucht und mochte beides nicht wirklich. Abgesehen davon halte ich Fabric für größtenteils orthogonal zu "vollständigen" Konfigurationsverwaltungssystemen wie diesen, daher ist dies kein wirklich fairer Vergleich. (Mit Fabric können Sie, sagen wir, 75-85 % des Weges dorthin schaffen, viele Leute tun das, und ich würde das gerne verbessern, wo wir können - aber Fabric wird immer eher eine Bottom-up-Bausteinbibliothek sein während die meisten CM-Tools wie Salt/Ansible/Chef/Puppet eher wie Top-Down-Frameworks sind.)

@bitprophet danke für deine Antwort.

Ich bin nicht glücklich mit Salz, ich bin nicht glücklich mit Stoff.

Fabric ist manchmal wie "Remote-Shell-Ausführung". Ich bin vor einigen Jahren von Shell-Skripten zu Python gewechselt, da ich Rückverfolgungen und Ausnahmen liebe. Die Shell-ähnliche Ausführung (bei Fehler in stdout/stderr schreiben und mit der nächsten Zeile fortfahren) ist in meinem Kontext nicht akzeptabel. Ich bevorzuge nicht abgefangene Ausnahmen gegenüber "bei Fehler fortfahren", insbesondere in Produktionssystemen.

Der Stoff fühlte sich an wie ein Schritt zurück.

Wir haben es einige Male benutzt, sind dann aber auf Salz umgestiegen.

Aber Salt ist zu kompliziert.

In meinem Team machen die meisten Entwickler einen großen Bogen um Salz.

Bei Stoff war das anders.

Ich sitze zwischen den Stühlen.

Ansible habe ich bisher noch nicht ausprobiert. Aber es scheint einfacher und das ist mir wichtig.

Ich hoffe, die folgenden Worte tun Ihnen nicht weh. ... Ich denke, ich werde nicht wieder auf Stoff umsteigen.

Für mich ist der Fabric ein Remote-Execution-Tool. SaltStack/Ansible/Puppet/Chef sind eine Art State-Management-Plattform. Das Ziel ist ein anderes.
Fabric bietet eine unkomplizierte Möglichkeit, den Remote-Host zu verwalten. Es gibt einige Bibliotheken, die eine Reihe von Codeschnipseln für Fabric anbieten. Es ist eine Richtung von "State Management".
Wenn wir möchten, dass Fabric ein komplexeres Remote-Ausführungsproblem löst, fordert es die Benutzer auf, ihre Komponenten zu schreiben, um die Verbindung oder andere Mitarbeiter zu handhaben. Mitogen eignet sich für diesen Fall.

Die Shell-ähnliche Ausführung (bei Fehler in stdout/stderr schreiben und mit der nächsten Zeile fortfahren) ist in meinem Kontext nicht akzeptabel. Ich bevorzuge nicht abgefangene Ausnahmen gegenüber "bei Fehler fortfahren", insbesondere in Produktionssystemen.

Um fair zu sein, Fabric sollte nicht wegen eines Fehlers weitermachen, also wenn Sie das sehen, passiert etwas anderes.

Das heißt, es ist immer noch nicht so sauber, was Ausnahmen angeht, wie wir es gerne hätten (im Grunde führen alle Fehler zu SystemExit) und Version 2 wird so gebaut, dass es viel ausnahmefreundlicher ist (wobei SystemExit nur an den äußersten Rändern der Programm.)

Hallo @bitprophet , nur um anzumerken, dass die Unterstützung von Python 3 für Mitogen heutzutage ein expliziteres Ziel ist. Es sollte nicht mehr als ein paar Wochen dauern, bis es erreicht ist, und es ist sowieso notwendig, Ansible auf kommenden Versionen von Fedora zu unterstützen.

Hallo @bitprophet , eine weitere Anmerkung, die besagt, dass Python 3 lange (laaaange) zuletzt den Master erreicht hat und das Ergebnis morgen Abend als erste stabile Serienveröffentlichung auf PyPI erscheinen wird. Die 'fakessh'-Unterstützung ist derzeit defekt und nicht im Umfang enthalten, aber ich möchte unbedingt daran festhalten, sie zu reparieren und für die TCP/UDP/Pipe-Weiterleitung zu verallgemeinern - in der Hoffnung, dass die Energie zurückkehrt, nachdem ich diese Python-3-Flaute hinter mir habe und viele neue Sachen werden jetzt ganz schnell passieren :)

Super, freut mich zu hören @dw! Ich weiß nicht, wann ich Zeit haben werde, mir die Mitogen-Integration meinerseits anzusehen, aber ich bin super begeistert, dass die Interpreter-Versions-Barriere jetzt weg ist 👍

@bitprophet irgendwelche Updates dazu?

@bitprophet diese Funktion ist sehr nützlich für unseren Zweck (Remote-Debugging), würde gerne bei der Implementierung auf jede erdenkliche Weise helfen.

Ich habe gerade von Mitogen erfahren, und ich denke, es wäre ein hervorragendes Backend für Fabric.

Tatsächlich denke ich, dass es eine Menge Fabric-Code (und möglicherweise auch den größten Teil von Pyinvoke) vorteilhaft ersetzen könnte. es hebt die „Sonderfall“-Unterscheidung zwischen Fabric/Invoke (ssh/local) auf und führt all dies in einem magischen „Kontext“ zusammen, der auch über Backends wie „sudo“ transparenter als Fabric (IMHO) funktioniert.

Im Moment fühle ich wirklich den Schmerz dieses Merkmals, das im Stoff fehlt. Ich betrachte die Implementierung von immer komplexerer Geschäftslogik auf dem Remote-Ende. im Moment geht es darum, Dateien mit sftp hin und her zu übertragen, um sicherzustellen, dass die Dinge richtig eingerichtet sind, und es ist ziemlich klobig. Es wäre so viel besser, dies einfach aus der Ferne zu tun: Öffnen Sie einfach die Datei, suchen Sie nach Inhalten, suchen/ersetzen und so weiter wird viel intuitiver.

Es ermöglicht auch das Schreiben von Python-Code, der außerhalb von Fabric wiederverwendbar ist. Im Moment kann ich das nicht wirklich tun, es sei denn, ich blinzle wirklich hart, weil der Python-Code im Grunde nur lokal ausgeführt wird. Also muss ich Dateien (oder Prozesse?!) Zwischen Hosts hin und her kopieren, um das zu tun, was ich brauche. das ist alles andere als ideal...

Im Moment bin ich an einer Kreuzung: Entweder ich gehe weiter die Fabric-Route, oder ich portiere einfach meinen gesamten Code nach Mitogen und mache einen kleinen Executor-Wrapper darum.. Ich benutze die fabfile -Funktion nicht genug um die Komplexität der Fabric zu gewährleisten, während Mitogen mir viel leistungsfähigere Funktionen für meinen Hauptanwendungsfall (der das Bootstrapping und die Wiederherstellung von Servern aus heterogenen Umgebungen ist) bietet ...

Aber ich verstehe, dass es natürlich auch andere Anwendungsfälle für Fabric und Invoke gibt. Ich denke nur, dass es viel natürlicher wäre, nativen Python-Code zu schreiben, selbst für vorhandene Funktionen in Fabric (wie Codeausführung), da Fehlerbehandlung, Pipe-Steuerung und vorhandene Reflexe mehr oder weniger normal funktionieren würden ...

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen