Skip to Content
IoT-App-EntwicklungIronFlock CLIEntfernte Maschinen über SSH

Entfernte Maschinen über SSH

--host führt einen ironflock-Befehl über SSH auf einer anderen Maschine aus statt auf dieser. Damit verwalten Sie Geräte von Ihrem Laptop aus, auch von einem Mac, ohne ironflock auf ihnen zu installieren. Mehrfach angegeben oder mit einer Hosts-Datei führt es den Befehl auf vielen Maschinen gleichzeitig aus.

ironflock --host [user@]machine <command> [flags] ironflock --host [user@]machine --host [user@]machine ... <command> [flags] ironflock --hosts <file> [--parallel <n>] <command> [flags]

Jeder Befehl außer completion läuft auf diese Weise auf einer anderen Maschine. --host, --hosts und --parallel sind globale Flags: Sie dürfen vor oder nach dem Namen des Befehls stehen.

Eine Maschine

--host [user@]machine führt denselben Befehl mit denselben Flags auf der angegebenen Maschine aus. Was er ausgibt, kommt unverändert zurück, stdout auf stdout und stderr auf stderr, und ebenso sein Exit-Code.

$ ironflock --host pi@device-17 version ironflock 2.0.2 linux/arm64 $ ironflock --host pi@device-17 agent remove --yes --json 2>/dev/null {"action":"removed","removed":[...]}

Was die andere Maschine braucht

  • Linux auf amd64, arm64 oder 32-Bit-ARM (v5 bis v7). Ein anderes System endet mit Exit-Code 3.
  • Einen SSH-Server, der Befehle ausführt. scp oder SFTP sind nicht nötig.
  • Eine POSIX-Login-Shell: sh, bash, dash oder zsh. csh, tcsh und fish enden mit Exit-Code 3 und einer Meldung, die das sagt.
  • root als SSH-Benutzer oder sudo für die Befehle, die Root-Rechte brauchen (siehe Root-Rechte auf der anderen Maschine).

Auf der Maschine muss ironflock nicht installiert sein: Jeder Lauf bringt seine eigene Binärdatei mit.

SSH-Einstellungen

--host verwendet das ssh dieser Maschine, sodass Ihre ~/.ssh/config, Ihre Schlüssel, der SSH-Agent und Jump-Hosts so funktionieren wie mit ssh. Es schaltet ab, was der Befehl nicht braucht: Agent- und X11-Weiterleitung, Port-Weiterleitungen, ein RemoteCommand und ein LocalCommand.

--host nimmt [user@]machine an und sonst nichts. Ein Port oder andere Optionen gehören in ~/.ssh/config:

Host device-* User pi Port 2222 StrictHostKeyChecking accept-new

Damit meldet sich ironflock --host device-17 status als pi auf Port 2222 an, und ssh akzeptiert den Host-Schlüssel eines Geräts, das es noch nicht kennt. Ein Wert von --host, der mit - beginnt, wird abgelehnt, ebenso einer mit anderen Zeichen als Buchstaben, Ziffern, ., _, - sowie dem : und % einer IPv6-Adresse.

Eine einzige SSH-Verbindung dient dem ganzen Lauf, wenn der Pfad ihres Control-Sockets kurz genug ist; der Socket wird im temporären Ordner angelegt, sonst unter /tmp. Dann fragt ssh nur einmal nach einem Passwort. Andernfalls öffnet jeder Schritt des Laufs seine eigene Verbindung, und ssh fragt für jeden erneut.

Ein Gerät, das ironflock agent install oder IronFlockOS eingerichtet hat, hat einen SSH-Benutzer für den Projekteigentümer, der sich mit dem Schlüssel aus der .flock-Datei des Geräts anmeldet. SSH-Zugriff zeigt den Benutzernamen und wie Sie den Schlüssel aus der Datei holen.

Was auf der Maschine geschieht

  1. Die Binärdatei. Die Maschine erhält die Binärdatei, die hier läuft, wenn sie dieselbe Plattform hat. Andernfalls lädt ironflock die Binärdatei für die Plattform der Maschine von <download base>/cli/<os>/<arch>/<version>/ironflock herunter und prüft sie hier, bevor es sie verwendet: ihre Signatur (.asc) gegen den Release-Schlüssel von IronFlock, den diese Binärdatei mitbringt, und ihre Build-Informationen, die das Programm ironflock, die Plattform der Maschine und dieselbe Quellrevision wie diese Binärdatei nennen müssen. Der Download wird in Ihrem Cache-Ordner aufbewahrt (~/.cache/ironflock unter Linux, ~/Library/Caches/ironflock auf einem Mac) und bei jeder Verwendung erneut geprüft.
  2. Der Ordner. Die Binärdatei kommt in einen neuen Ordner, den nur der SSH-Benutzer lesen kann (mktemp -d), unter ${TMPDIR:-/tmp} auf der Maschine oder im Home-Verzeichnis des SSH-Benutzers, wenn ein Programm im temporären Ordner nicht laufen kann (ein mit noexec eingehängtes Dateisystem). Kann es in keinem von beiden laufen, endet der Befehl mit Exit-Code 3 und nennt beide. Bevor sie irgendetwas aus dem Ordner ausführt, prüft die Maschine, dass der Ordner und die Binärdatei dem SSH-Benutzer gehören und keine symbolischen Links sind und dass die Binärdatei die erwartete Version und Plattform hat.
  3. Die Dateien. Die in den Flags des Befehls genannten Dateien gehen mit (siehe In Flags genannte Dateien).
  4. Der Befehl. Er läuft als SSH-Benutzer oder über sudo (siehe Root-Rechte auf der anderen Maschine).
  5. Das Aufräumen. Wenn der Befehl endet, entfernt die Maschine den Ordner mit der Binärdatei und den Kopien: auch nach einem Fehler, nach einer verlorenen Verbindung und nach den Signalen HUP, INT, QUIT, TERM, PIPE, USR1 und USR2.

--host hinterlässt kein ironflock auf der Maschine, auch nicht nach agent install. Arbeiten Sie von hier aus mit --host weiter, oder installieren Sie ironflock auf der Maschine mit der Installationszeile, die es ohne Argumente nur installiert. self-update über --host aktualisiert dieses /usr/local/bin/ironflock der Maschine, nicht die Binärdatei des Laufs (ironflock self-update).

Ein Ordner ironflock.* bleibt in zwei Fällen auf der Maschine zurück:

  • Nach einem Stromausfall oder einem kill -9 auf der Maschine, während der Befehl läuft. Der Ordner enthält die Binärdatei und die Kopien.
  • Wenn die Verbindung nach dem Kopieren und vor dem Start des Befehls verloren geht oder der Lauf hier unterbrochen wird, während der Schritt, der den Befehl startet, die Verbindung aufbaut. Der Ordner enthält die Binärdatei und auch die Kopien, wenn Sie den Befehl an einem Terminal ausgeführt haben.

Eine Kopie einer .flock-Datei enthält das Secret des Geräts, eine Kopie einer Passphrasendatei die WLAN-Passphrase, eine Kopie einer Passwortdatei das Proxy-Passwort. Nur der SSH-Benutzer und root können sie lesen. Entfernen Sie einen solchen Ordner von Hand.

In Flags genannte Dateien

FlagBefehle
-c, --config (die .flock-Datei)agent install, agent configure, doctor, os flash, os install, os reset
--wifi-password-fileos flash
--proxy-password-fileagent install, agent configure, os install

Jede Datei wird hier gelesen, und ein relativer Pfad ist relativ zum Arbeitsordner dieser Maschine. Eine Passphrasen- oder Passwortdatei darf eine Pipe sein (/dev/stdin), die einmal gelesen wird. Der Inhalt geht über die Standardeingabe der SSH-Verbindung an die Maschine. Weder eine Datei noch ihre Größe steht auf einer Befehlszeile, weder hier noch auf der Maschine, wo jeder Benutzer Befehlszeilen lesen kann. Die Maschine prüft jede Größe gegen die größte, die der Befehl annimmt, und dann, dass alles angekommen ist.

Auf der Maschine ist die Kopie <folder>/1/device.flock: in einem eigenen Ordner (Modus 0700) im Ordner des Laufs, mit dem Namen, den sie hier hat, und Modus 0600. Der Befehl dort erhält diesen Pfad, zum Beispiel --config=/tmp/ironflock.k3Xf9QpL2m/1/device.flock, sodass ein Fehler zum Inhalt der Datei die Kopie nennt.

Diese Fälle beenden den Befehl auf dieser Maschine:

  • Exit-Code 1 — eine Datei, die keine reguläre Datei ist (eine Passphrasen- oder Passwortdatei darf auch eine Pipe sein), oder eine, die größer ist, als der Befehl annimmt: 5 MiB für eine .flock-Datei, 4096 Bytes für eine Passphrasen- oder Passwortdatei.
  • Exit-Code 2 — ein Dateiname mit einem Steuerzeichen.
  • Exit-Code 2 — --image-file und --output von os flash. --host kopiert kein Image auf die Maschine und holt keine Datei zurück. Führen Sie diesen Befehl hier ohne --host aus oder auf der Maschine selbst. Ohne --image-file lädt die Maschine das Image selbst herunter.

Root-Rechte auf der anderen Maschine

  • Ein Befehl, der Root-Rechte braucht, läuft über sudo, wenn der SSH-Benutzer nicht root ist. sudo ohne Passwort und ohne Terminal funktioniert überall.
  • version, os images und os drives laufen als SSH-Benutzer.
  • status und doctor lesen mit Root-Rechten mehr. Sie laufen als root, wenn der SSH-Benutzer root ist oder sudo ohne Passwort und ohne Terminal verwenden darf. Andernfalls laufen sie als SSH-Benutzer, ohne zu fragen, und ihr Hinweis nennt den Befehl mit --host root@machine.
  • agent logs liest eine Datei, die root gehört, und läuft über sudo.
  • Wenn sudo nach einem Passwort fragt oder seine Konfiguration ein Terminal verlangt (requiretty), braucht es ein Terminal auf der Maschine. Dafür braucht es hier ein Terminal auf stdin, stdout und stderr. Ohne Terminal endet der Befehl mit Exit-Code 3, bevor irgendetwas kopiert wird. Melden Sie sich dann als root an, erlauben Sie dem SSH-Benutzer sudo ohne Passwort und ohne Terminal, oder führen Sie den Befehl an einem Terminal ohne Umleitung aus.
  • Ein sudo, das ablehnt, wenn der Befehl gerade starten soll, endet ebenfalls mit Exit-Code 3.

Was der Befehl dort als Nächstes auszuführen empfiehlt, ist ein Befehl für diese Seite, ohne sudo, da --host sich die Root-Rechte selbst holt: ironflock --host pi@device-17 agent start.

Terminal, Fragen und Ausgabe

  • Mit einem Terminal hier erhält der Befehl auch auf der Maschine eines, sodass er seine Fragen stellen kann. Seine stdout und stderr kommen dann zusammen zurück, auf Ihr Terminal.
  • Ohne Terminal hier (eine Pipe, --json in ein Programm, CI) bleiben stdout und stderr getrennt, und der Befehl fragt nichts: --yes bestätigt. Was die Dateien des SSH-Benutzers auf der Maschine ausgeben, etwa eine .bashrc, die Text ausgibt, wird aus stdout entfernt, sodass stdout nur das Ergebnis des Befehls enthält.
  • --yes, --json und die Flags des Befehls gehen mit. Die Download-Basis geht als --download-base mit: das Flag oder IRONFLOCK_DL_BASE dieser Maschine. Eine Download-Basis mit Anmeldedaten (https://user:[email protected]/dl) endet mit Exit-Code 2, bevor irgendeine Maschine erreicht wird, da sie auf der Maschine auf einer Befehlszeile stünde, die dort jeder Benutzer lesen kann.
  • --help, help, eine Gruppe ohne Befehl und completion werden hier beantwortet: Was sie ausgeben, ist auf jeder Maschine gleich.
  • Was die Maschine auf stdout sendet, bevor der Befehl läuft (ihre Antworten und der Text der Dateien des SSH-Benutzers), wird bis zu 64 KiB gelesen. Mehr beendet den Lauf mit Exit-Code 1, bevor der Befehl dort läuft.

Strg+C und verlorene Verbindungen

Strg+C hier erreicht den Befehl dort so, wie Strg+C an seinem eigenen Terminal es täte, und eine verlorene Verbindung erreicht ihn als Hangup, mit und ohne Terminal hier. Nach Strg+C wartet --host bis zu 15 Sekunden darauf, dass die Maschine meldet, dass der Befehl dort geendet hat, mit seinem Exit-Code (130, wenn Strg+C ihn beendet hat). Meldet die Maschine das nicht rechtzeitig oder endet die Verbindung vorher, endet --host mit 130 und sagt, dass der Befehl dort möglicherweise noch läuft. Ein Lauf, dessen Befehl noch nicht gestartet war, als Strg+C kam, startet ihn nicht mehr.

os install über --host hat eigene Regeln: Sobald seine Frage beantwortet ist, hält eine verlorene Verbindung es nicht mehr an, und der Befehl wartet hier darauf, dass die Maschine als IronFlockOS zurückkommt; siehe ironflock os install.

Exit-Codes und Fehler

Die Exit-Codes sind die des Befehls (Exit-Codes). --host fügt diese hinzu:

CodeBedeutung
255ssh ist fehlgeschlagen: keine Verbindung, die Anmeldung oder der Host-Schlüssel wurde abgelehnt, eine abgebrochene Verbindung
3die Maschine kann den Befehl nicht ausführen: ein anderes System oder eine andere CPU, eine Login-Shell, die keine POSIX-Shell ist, kein Ordner, in dem ein Programm laufen kann, ein sudo, das den SSH-Benutzer nicht zulässt
130eine Unterbrechung, hier (Strg+C) oder des Befehls auf der Maschine (dort ein Hangup-, Interrupt- oder Terminate-Signal)

Ein Fehler von --host selbst ist ein Fehler wie jeder andere: eine Error:-Zeile auf stderr oder mit --json das Fehlerobjekt auf stdout. Die einzige Ausnahme: Wenn die Ausgabe des Befehls bereits durchgekommen war, ist diese Ausgabe das Ergebnis, und der Fehler ist allein die Error:-Zeile auf stderr, auch mit --json.

Mehrere Maschinen

Mehrfach angegebenes --host oder --hosts <file> führt den Befehl auf jeder Maschine aus, so wie --host ihn auf einer ausführt. Die Maschinen von --host kommen zuerst, dann die aus der Datei. Eine Hosts-Datei mit nur einer Maschine darin läuft wie bei mehreren Maschinen.

$ ironflock --host pi@vm1 --host pi@vm2 --host pi@vm3 status pi@vm2: Agent: installed in /opt/ironflock/device-agent pi@vm2: Version: 1.6.9 pi@vm2: Service: running (ironflock-device-agent.service) pi@vm3: ssh: connect to host vm3 port 22: Connection timed out pi@vm3: Error: the SSH connection to pi@vm3 failed pi@vm1: Agent: installed in /opt/ironflock/device-agent ... Summary of "status" on 3 machines, exit code 255: 2 done, 1 ssh. pi@vm1 done pi@vm2 done pi@vm3 255 ssh: the SSH connection to pi@vm3 failed (ssh: connect to host vm3 port 22: Connection timed out)

Die Hosts-Datei

Die Datei nennt ein [user@]machine pro Zeile. Ein # beginnt einen Kommentar, der bis zum Zeilenende reicht, und leere Zeilen werden übersprungen. Die Datei darf auch eine Pipe sein, etwa --hosts <(...), und ist höchstens 1 MiB groß.

# Verpackungslinie 3 pi@device-17 pi@device-18 pi@device-19 # the spare unit
# Den Zustand jeder Maschine in der Datei anzeigen, 20 gleichzeitig ironflock --hosts line3.txt --parallel 20 status # Den Agenten auf jeder Maschine in der Datei aktualisieren; agent update fragt, daher ist --yes nötig ironflock --hosts line3.txt agent update --yes # Den Geräten eines Standorts ein Proxy-Konto geben; das Passwort kommt aus einer Datei ironflock --hosts site-a.txt agent configure --https-proxy http://[email protected]:3128 --proxy-password-file proxy-password.txt --yes

Diese Fälle enden mit Exit-Code 2, bevor irgendetwas läuft, und der Fehler nennt die Datei und die Zeile:

  • eine Zeile mit mehr als einem Wort;
  • eine Maschine, die --host ablehnen würde;
  • eine zweimal genannte Maschine. Zweimal ist auch dieselbe Maschine mit zwei Benutzern, da der Befehl sonst zweimal gleichzeitig auf ihr liefe. Eine Adresse und ein Name derselben Maschine werden nicht als dieselbe Maschine erkannt.

Parallele Läufe

Höchstens --parallel Maschinen laufen gleichzeitig: 10 ohne das Flag, von 1 bis 100. Sie starten in der angegebenen Reihenfolge, und die nächste startet, wenn eine endet. --parallel ohne mehrere Maschinen endet mit Exit-Code 2.

SSH ohne Fragen

Keine Maschine erhält ein Terminal, und ssh fragt nichts (BatchMode=yes). Diese Fälle scheitern auf der betreffenden Maschine mit Exit-Code 255 und den eigenen Worten von ssh, und die anderen Maschinen laufen weiter:

  • eine Anmeldung, die ein Passwort verlangt;
  • ein Schlüssel, dessen Passphrase nicht im SSH-Agenten ist;
  • ein Host-Schlüssel, den ssh noch nicht kennt.

Verbinden Sie sich einmal mit ssh, um einen neuen Host-Schlüssel zu akzeptieren, oder setzen Sie StrictHostKeyChecking accept-new für diese Maschinen in ~/.ssh/config, wie im Beispiel oben. ssh gibt den Verbindungsaufbau nach 30 Sekunden auf (ConnectTimeout=30, unabhängig davon, was ~/.ssh/config sagt), sodass eine ausgeschaltete Maschine dann gemeldet wird. Ein sudo dort, das ein Passwort oder ein Terminal verlangt, endet auf dieser Maschine mit Exit-Code 3; status und doctor laufen dann als SSH-Benutzer.

Ausgabe mehrerer Maschinen

  • Jede Zeile, die eine Maschine schreibt, kommt vollständig, mit <host>: davor: ihre stdout auf stdout, ihre stderr auf stderr. Die Zeilen der Maschinen mischen sich in der Reihenfolge, in der sie kommen.
  • Eine letzte Zeile ohne Zeilenumbruch erhält einen. Eine Zeile, die länger als 64 KiB ist, kommt in Teilen von 64 KiB, jeder mit dem Host davor.
  • Steuerzeichen außer dem Tabulator kommen maskiert (\x1b, \r), in den Zeilen und in der Zusammenfassung, sodass keine Maschine den Cursor bewegt oder die Zeile einer anderen Maschine überschreibt. Ein Wagenrücklauf am Ende einer Zeile wird entfernt.
  • Ein Lauf, der hier fehlschlägt, fügt seine Error:-Zeile mit dem Host davor hinzu, so wie --host sie für eine Maschine schreibt.
  • Am Ende erhält stderr eine Zusammenfassung: den Exit-Code und wie viele Maschinen wie geendet haben, dann eine Zeile für jede Maschine in der angegebenen Reihenfolge. Die Zeile sagt done oder nennt den Exit-Code, seine Art und den Grund: den Fehler hier (bei 255 mit den eigenen Worten von ssh) oder die Error:-Zeile des Befehls. Eine Maschine, die das Ende ihres Befehls nach Strg+C nicht bestätigt hat, ist interrupted, may still run.

Exit-Code mehrerer Maschinen

Der Befehl endet mit dem schlechtesten Exit-Code der Maschinen: 0, wenn jede Maschine mit 0 geendet hat. Andernfalls, vom schlechtesten an:

  1. 130 — unterbrochen, hier oder auf einer Maschine.
  2. 1 — der Befehl ist auf einer Maschine fehlgeschlagen und hat sie möglicherweise halb geändert zurückgelassen, mit welchem Code er dort auch geendet hat.
  3. 255 — eine Maschine wurde nicht erreicht, oder die Verbindung brach ab.
  4. 3 — eine Maschine war nicht in dem Zustand, den der Befehl braucht, oder kann ihn nicht ausführen.
  5. 4 — eine Frage wurde mit Nein beantwortet.

Exit-Code 2 ist hier eine falsche Befehlszeile, wie bei jedem Befehl.

JSON-Zeilen

Mit --json erhält stdout eine Zeile für jede Maschine, wenn ihr Befehl geendet hat, in der Reihenfolge, in der sie enden, und sonst nichts. Ein Programm liest die Zeilen, sobald sie kommen.

{"host":"pi@vm1","state":"done","exit_code":0,"result":{...}}
FeldBedeutung
hostdie Maschine, wie --host oder die Hosts-Datei sie nennt
statedone: Der Befehl hat mit 0 geendet. failed: Er hat dort mit einem anderen Code geendet, oder sein Lauf ist hier fehlgeschlagen. interrupted: Der Lauf wurde unterbrochen, und die Maschine hat gemeldet, dass der Befehl geendet hat. may_still_run: Der Lauf wurde hier unterbrochen, und die Maschine hat innerhalb der Wartezeit nicht gemeldet, dass der Befehl geendet hat. not_started: Der Lauf wurde unterbrochen, bevor die Maschine an der Reihe war; dort lief nichts.
exit_codewie der Befehl auf der Maschine geendet hat oder wie sein Lauf hier geendet hat: 255, wenn die Maschine nicht erreicht wurde oder die Verbindung abbrach, 3, wenn die Maschine den Befehl nicht ausführen kann, 130, wenn der Lauf unterbrochen wurde. Ein anderer Code, etwa 137 nach einem Kill, ist unverändert der der Maschine, mit dem Zustand failed.
resultwas der Befehl mit --json geschrieben hat, wie es die Seite des Befehls beschreibt. Bei agent logs das Array seiner Zeilen; höchstens 16 MiB werden behalten. Ein Befehl, der sein Ergebnis schreibt und mit 1 endet (doctor, agent update), hat es ebenfalls.
errorwarum der Befehl nicht mit 0 geendet hat, mit kind und message: der Fehler des Laufs hier (Art ssh für eine Maschine, die nicht erreicht wurde, wobei die Meldung mit den Worten von ssh in Klammern endet), sonst das Fehlerobjekt des Befehls, sonst eines aus seinem Exit-Code und seiner letzten Zeile auf stderr
outputwas der Befehl auf stdout geschrieben hat und kein JSON ist; oder, wenn er mehr als 16 MiB geschrieben hat, ein Satz, der das sagt

stderr enthält die Zeilen der Maschinen, darunter die eigene Error:-Zeile eines Befehls, wo er mit --json eine schreibt (agent update), und die Zusammenfassung. Die Fehler der Läufe hier stehen nur in den Zeilen auf stdout.

# Die Maschinen, auf denen status nicht mit 0 geendet hat ironflock --hosts line3.txt status --json 2>/dev/null | jq -r 'select(.state != "done") | .host'

Strg+C auf mehreren Maschinen

Strg+C, SIGTERM oder SIGHUP beendet die Läufe so, wie es einen Lauf auf einer Maschine beendet: Jeder Befehl dort erhält das Signal, und jede Maschine hat 15 Sekunden, um zu bestätigen, dass ihr Befehl geendet hat. Eine Maschine, die das nicht tut, ist may_still_run. Die Maschinen, die noch nicht an der Reihe waren, führen nichts aus. Die Zusammenfassung listet sie als not started, und der Befehl endet mit 130.

Welche Befehle auf mehreren Maschinen laufen

BefehleAuf mehreren Maschinen
version, status, doctor, os images, os drives, agent restart, agent startimmer
agent logsimmer; mit --follow nicht mit --json, da die Zeile einer Maschine kommt, wenn ihr Befehl endet, und --follow nicht endet
agent stop, agent update, agent configure, agent remove, os update, os rollback, self-updatemit --yes: Sie fragen, und auf mehreren Maschinen gleichzeitig wird niemand gefragt
completionhier beantwortet und auf keiner Maschine, wie --help
agent install, os install, os flash, os resetgar nicht: Ihre .flock-Datei nennt ein einzelnes Gerät, oder sie löschen eine Festplatte, ein Laufwerk oder die Daten eines Geräts nach einer Frage, die die eine Maschine nennt

Ein Flag, das eine Datei auf dieser Maschine nennt, wird bei mehreren Maschinen abgelehnt, da die Datei an jede Maschine ginge: -c von doctor und von agent configure nennt ein einzelnes Gerät. Die Ausnahme ist --proxy-password-file von agent configure, für ein Proxy-Konto für die Maschinen eines Standorts.

Eine Befehlszeile, die nicht auf mehreren Maschinen läuft, endet mit Exit-Code 2 und sagt, warum, bevor die Hosts-Datei gelesen und bevor irgendeine Maschine erreicht wird.

Last updated on