Zdalne maszyny przez SSH
--host uruchamia polecenie ironflock na innej maszynie przez SSH zamiast na tej. Dzięki temu zarządzasz urządzeniami ze swojego laptopa, także z Maca, bez instalowania na nich ironflock. Gdy podasz tę flagę kilka razy albo użyjesz pliku hostów, polecenie działa na wielu maszynach jednocześnie.
ironflock --host [user@]machine <command> [flags]
ironflock --host [user@]machine --host [user@]machine ... <command> [flags]
ironflock --hosts <file> [--parallel <n>] <command> [flags]W ten sposób na innej maszynie działa każde polecenie poza completion. --host, --hosts i --parallel to flagi globalne: mogą stać przed nazwą polecenia lub po niej.
Jedna maszyna
--host [user@]machine uruchamia to samo polecenie z tymi samymi flagami na wskazanej maszynie. To, co polecenie wypisuje, wraca bez zmian, stdout na stdout i stderr na stderr, podobnie jak jego kod wyjścia.
$ 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":[...]}Czego potrzebuje zdalna maszyna
- Linux na amd64, arm64 lub 32-bitowym ARM (v5 do v7). Inny system kończy się kodem wyjścia 3.
- Serwer SSH, który wykonuje polecenia.
scpani SFTP nie są potrzebne. - Powłoka logowania POSIX: sh, bash, dash lub zsh. csh, tcsh i fish kończą się kodem wyjścia 3 i komunikatem, który o tym mówi.
- Logowanie jako root albo
sudodla poleceń wymagających roota (zobacz Root na zdalnej maszynie).
Maszyna nie potrzebuje zainstalowanego ironflock: każde uruchomienie przynosi własny plik binarny.
Ustawienia SSH
--host używa ssh tej maszyny, więc twój ~/.ssh/config, klucze, agent SSH i hosty pośredniczące (jump hosts) działają tak samo jak z ssh. Wyłącza to, czego polecenie nie potrzebuje: przekazywanie agenta i X11, przekierowania portów, RemoteCommand i LocalCommand.
--host przyjmuje [user@]machine i nic więcej. Port lub inne opcje trafiają do ~/.ssh/config:
Host device-*
User pi
Port 2222
StrictHostKeyChecking accept-newWtedy ironflock --host device-17 status loguje się jako pi na porcie 2222, a ssh akceptuje klucz hosta urządzenia, którego jeszcze nie zna. Wartość --host zaczynająca się od - jest odrzucana, podobnie jak wartość zawierająca inne znaki niż litery, cyfry, ., _, - oraz : i % adresu IPv6.
Jedno połączenie SSH obsługuje całe uruchomienie, gdy ścieżka jego gniazda sterującego jest wystarczająco krótka; gniazdo powstaje w folderze tymczasowym, a w przeciwnym razie w /tmp. Wtedy ssh pyta o hasło tylko raz. W przeciwnym razie każdy krok uruchomienia otwiera własne połączenie, a ssh pyta o hasło przy każdym z nich.
Urządzenie skonfigurowane przez ironflock agent install lub IronFlockOS ma użytkownika SSH dla właściciela projektu, który loguje się kluczem z pliku .flock urządzenia. Dostęp SSH pokazuje nazwę użytkownika i sposób wyjęcia klucza z pliku.
Co dzieje się na maszynie
- Plik binarny. Maszyna dostaje plik binarny działający tutaj, gdy ma tę samą platformę. W przeciwnym razie
ironflockpobiera plik binarny dla platformy maszyny z<download base>/cli/<os>/<arch>/<version>/ironflocki sprawdza go tutaj, zanim go użyje: jego podpis (.asc) kluczem wydań IronFlock, który zawiera ten plik binarny, oraz jego informacje o kompilacji, które muszą wskazywać programironflock, platformę maszyny i tę samą rewizję źródeł co ten plik binarny. Pobrany plik jest przechowywany w twoim folderze pamięci podręcznej (~/.cache/ironflockw Linuksie,~/Library/Caches/ironflockna Macu) i sprawdzany ponownie przy każdym użyciu. - Folder. Plik binarny trafia do nowego folderu, który może odczytać tylko konto SSH (
mktemp -d), w${TMPDIR:-/tmp}na maszynie albo w folderze domowym konta SSH, gdy program nie może działać w folderze tymczasowym (system plików zamontowany znoexec). Gdy nie może działać w żadnym z nich, polecenie kończy się kodem wyjścia 3 i podaje oba foldery. Zanim cokolwiek uruchomi z tego folderu, maszyna sprawdza, czy folder i plik binarny należą do konta SSH i nie są dowiązaniami symbolicznymi oraz czy plik binarny ma oczekiwaną wersję i platformę. - Pliki. Pliki wskazane we flagach polecenia są przesyłane razem z nim (zobacz Pliki wskazane we flagach).
- Polecenie. Działa z uprawnieniami konta SSH albo przez
sudo(zobacz Root na zdalnej maszynie). - Sprzątanie. Gdy polecenie się kończy, maszyna usuwa folder z plikiem binarnym i kopiami: także po błędzie, po utracie połączenia i po sygnałach HUP, INT, QUIT, TERM, PIPE, USR1 i USR2.
--host nie zostawia na maszynie ironflock, także po agent install. Kontynuuj stąd z --host albo zainstaluj ironflock na maszynie poleceniem instalacyjnym, które bez argumentów tylko go instaluje. self-update przez --host aktualizuje ten /usr/local/bin/ironflock na maszynie, a nie plik binarny uruchomienia (ironflock self-update).
Folder ironflock.* zostaje na maszynie w dwóch przypadkach:
- Po utracie zasilania lub
kill -9na maszynie w trakcie działania polecenia. Folder zawiera plik binarny i kopie. - Gdy połączenie zostanie utracone po skopiowaniu, a przed startem polecenia, albo gdy uruchomienie zostanie przerwane tutaj w chwili, gdy krok startujący polecenie nawiązuje połączenie. Folder zawiera plik binarny, a także kopie, jeśli polecenie uruchomiono w terminalu.
Kopia pliku .flock zawiera sekret urządzenia, kopia pliku z hasłem WiFi zawiera hasło WiFi, a kopia pliku z hasłem proxy zawiera hasło proxy. Odczytać je mogą tylko konto SSH i root. Taki folder usuń ręcznie.
Pliki wskazane we flagach
| Flaga | Polecenia |
|---|---|
-c, --config (plik .flock) | agent install, agent configure, doctor, os flash, os install, os reset |
--wifi-password-file | os flash |
--proxy-password-file | agent install, agent configure, os install |
Każdy plik jest odczytywany tutaj, a ścieżka względna odnosi się do bieżącego folderu roboczego tej maszyny. Plik z hasłem WiFi lub hasłem proxy może być potokiem (/dev/stdin), który jest odczytywany raz. Zawartość trafia na maszynę przez standardowe wejście połączenia SSH. Ani plik, ani jego rozmiar nie pojawiają się w wierszu poleceń, ani tutaj, ani na maszynie, gdzie każdy użytkownik może odczytać wiersze poleceń. Maszyna sprawdza każdy rozmiar względem największego, jaki przyjmuje polecenie, a potem, czy dotarła cała zawartość.
Na maszynie kopią jest <folder>/1/device.flock: we własnym folderze (tryb 0700) w folderze uruchomienia, z nazwą, jaką plik ma tutaj, i trybem 0600. Polecenie na maszynie dostaje tę ścieżkę, na przykład --config=/tmp/ironflock.k3Xf9QpL2m/1/device.flock, więc błąd dotyczący zawartości pliku wskazuje kopię.
Te sytuacje kończą polecenie na tej maszynie:
- Kod wyjścia 1 — plik, który nie jest zwykłym plikiem (plik z hasłem WiFi lub hasłem proxy może też być potokiem), albo plik większy, niż przyjmuje polecenie: 5 MiB dla pliku
.flock, 4096 bajtów dla pliku z hasłem WiFi lub hasłem proxy. - Kod wyjścia 2 — nazwa pliku ze znakiem sterującym.
- Kod wyjścia 2 —
--image-filei--outputpoleceniaos flash.--hostnie kopiuje obrazu na maszynę i nie przynosi z powrotem żadnego pliku. Uruchom to polecenie tutaj bez--hostalbo na samej maszynie. Bez--image-filemaszyna sama pobiera obraz.
Root na zdalnej maszynie
- Polecenie wymagające roota działa przez
sudo, gdy konto SSH nie jest kontem root.sudobez hasła i bez terminala działa wszędzie. version,os imagesios drivesdziałają z uprawnieniami konta SSH.statusidoctorodczytują więcej jako root. Działają jako root, gdy konto SSH jest kontem root lub może używaćsudobez hasła i bez terminala. W przeciwnym razie działają z uprawnieniami konta SSH, bez pytania, a ich wskazówka podaje polecenie z--host root@machine.agent logsczyta plik należący do roota i działa przezsudo.- Gdy
sudopyta o hasło albo jego konfiguracja wymaga terminala (requiretty), potrzebuje terminala na maszynie. To z kolei wymaga terminala na stdin, stdout i stderr tutaj. Bez niego polecenie kończy się kodem wyjścia 3, zanim cokolwiek zostanie skopiowane. Wtedy zaloguj się jako root, pozwól kontu SSH używaćsudobez hasła i bez terminala albo uruchom polecenie w terminalu bez przekierowań. sudo, które odmawia w chwili uruchamiania polecenia, również kończy się kodem wyjścia 3.
To, co polecenie na maszynie każe uruchomić w następnej kolejności, jest poleceniem dla tej strony, bez sudo, ponieważ --host samo uzyskuje roota: ironflock --host pi@device-17 agent start.
Terminal, pytania i wyjście
- Gdy tutaj jest terminal, polecenie dostaje terminal także na maszynie, więc może zadawać pytania. Jego stdout i stderr wracają wtedy razem, do twojego terminala.
- Bez terminala tutaj (potok,
--jsondo programu, CI) stdout i stderr pozostają rozdzielone, a polecenie o nic nie pyta: potwierdza--yes. To, co wypisują pliki konta SSH na maszynie, na przykład.bashrcz poleceniem echo, jest usuwane ze stdout, tak aby stdout zawierał tylko wynik polecenia. --yes,--jsoni flagi polecenia są przekazywane dalej. Bazowy adres pobierania jest przekazywany jako--download-base: flaga alboIRONFLOCK_DL_BASEtej maszyny. Bazowy adres pobierania z danymi logowania (https://user:[email protected]/dl) kończy się kodem wyjścia 2, zanim nastąpi połączenie z jakąkolwiek maszyną, ponieważ na maszynie znalazłby się w wierszu poleceń, który może odczytać każdy jej użytkownik.--help,help, grupa bez polecenia icompletionsą obsługiwane tutaj: to, co wypisują, jest takie samo na każdej maszynie.- To, co maszyna wysyła na stdout przed uruchomieniem polecenia (jej odpowiedzi i tekst z plików konta SSH), jest odczytywane do 64 KiB. Więcej kończy uruchomienie kodem wyjścia 1, zanim polecenie zacznie tam działać.
Ctrl-C i utracone połączenia
Ctrl-C tutaj dociera do polecenia na maszynie tak, jak dotarłoby Ctrl-C w jego własnym terminalu, a utracone połączenie dociera do niego jako sygnał rozłączenia, z terminalem tutaj i bez niego. Po Ctrl-C --host czeka do 15 sekund, aż maszyna poinformuje, że polecenie się zakończyło, i poda jego kod wyjścia (130, gdy zakończyło je Ctrl-C). Gdy maszyna nie zrobi tego na czas albo połączenie zakończy się wcześniej, --host kończy się kodem 130 i informuje, że polecenie może tam nadal działać. Uruchomienie, którego polecenie jeszcze nie wystartowało w chwili Ctrl-C, już go nie uruchamia.
os install przez --host ma własne zasady: gdy padnie już odpowiedź na jego pytanie, utrata połączenia go nie zatrzymuje, a polecenie czeka tutaj, aż maszyna wróci jako IronFlockOS; zobacz ironflock os install.
Kody wyjścia i błędy
Kody wyjścia to kody polecenia (Kody wyjścia). --host dodaje te:
| Kod | Znaczenie |
|---|---|
| 255 | ssh nie powiodło się: brak połączenia, odrzucone logowanie lub klucz hosta, zerwane połączenie |
| 3 | maszyna nie może uruchomić polecenia: inny system lub procesor, powłoka logowania, która nie jest powłoką POSIX, brak folderu, w którym może działać program, sudo, które nie dopuszcza konta SSH |
| 130 | przerwanie, tutaj (Ctrl-C) albo polecenia na maszynie (tamtejszy sygnał rozłączenia, przerwania lub zakończenia) |
Błąd samego --host jest błędem jak każdy inny: wiersz Error: na stderr albo, z --json, obiekt błędu na stdout. Jedyny wyjątek: gdy wyjście polecenia zdążyło już dotrzeć, to wyjście jest wynikiem, a błąd to tylko wiersz Error: na stderr, także z --json.
Kilka maszyn
--host podane kilka razy albo --hosts <file> uruchamia polecenie na każdej maszynie, tak jak --host uruchamia je na jednej. Najpierw idą maszyny z --host, potem te z pliku. Plik hostów z jedną maszyną działa tak jak kilka maszyn.
$ 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)Plik hostów
Plik wymienia po jednym [user@]machine w wierszu. # zaczyna komentarz, który biegnie do końca wiersza, a puste wiersze są pomijane. Plik może być też potokiem, na przykład --hosts <(...), i ma najwyżej 1 MiB.
# Linia pakowania 3
pi@device-17
pi@device-18
pi@device-19 # the spare unit# Pokaż stan każdej maszyny z pliku, po 20 naraz
ironflock --hosts line3.txt --parallel 20 status
# Zaktualizuj agenta na każdej maszynie z pliku; agent update zadaje pytanie, więc potrzebne jest --yes
ironflock --hosts line3.txt agent update --yes
# Daj urządzeniom jednej lokalizacji jedno konto proxy; hasło pochodzi z pliku
ironflock --hosts site-a.txt agent configure --https-proxy http://[email protected]:3128 --proxy-password-file proxy-password.txt --yesTe sytuacje kończą się kodem wyjścia 2, zanim cokolwiek się uruchomi, a komunikat błędu podaje plik i wiersz:
- wiersz z więcej niż jednym słowem;
- maszyna, którą odrzuciłoby
--host; - maszyna podana dwa razy. Dwa razy to także ta sama maszyna z dwoma użytkownikami, ponieważ polecenie działałoby na niej dwukrotnie jednocześnie. Adres i nazwa tej samej maszyny nie są rozpoznawane jako ta sama maszyna.
Uruchomienia równoległe
Jednocześnie działa najwyżej --parallel maszyn: 10 bez tej flagi, od 1 do 100. Startują w podanej kolejności, a następna startuje, gdy któraś się zakończy. --parallel bez kilku maszyn kończy się kodem wyjścia 2.
SSH bez pytań
Żadna maszyna nie dostaje terminala, a ssh o nic nie pyta (BatchMode=yes). Te sytuacje kończą się na danej maszynie kodem wyjścia 255 i komunikatem samego ssh, a pozostałe maszyny działają dalej:
- logowanie, które wymaga hasła;
- klucz, którego hasła nie ma w agencie SSH;
- klucz hosta, którego
sshjeszcze nie zna.
Połącz się raz przez ssh, aby zaakceptować nowy klucz hosta, albo ustaw StrictHostKeyChecking accept-new dla tych maszyn w ~/.ssh/config, jak w przykładzie powyżej. ssh przestaje próbować połączenia po 30 sekundach (ConnectTimeout=30, niezależnie od ~/.ssh/config), więc wyłączona maszyna jest wtedy zgłaszana. sudo na maszynie, które wymaga hasła lub terminala, kończy się na tej maszynie kodem wyjścia 3; status i doctor działają wtedy z uprawnieniami konta SSH.
Wyjście kilku maszyn
- Każdy wiersz zapisany przez maszynę przychodzi w całości, poprzedzony
<host>:: jej stdout na stdout, jej stderr na stderr. Wiersze maszyn mieszają się w kolejności nadejścia. - Ostatni wiersz bez znaku nowego wiersza dostaje go. Wiersz dłuższy niż 64 KiB przychodzi w częściach po 64 KiB, każda poprzedzona hostem.
- Znaki sterujące inne niż tabulator przychodzą w postaci sekwencji ucieczki (
\x1b,\r), w wierszach i w podsumowaniu, tak aby żadna maszyna nie przesuwała kursora ani nie nadpisywała wiersza innej maszyny. Znak powrotu karetki na końcu wiersza jest usuwany. - Uruchomienie, które nie powiedzie się tutaj, dodaje swój wiersz
Error:poprzedzony hostem, tak jak--hostzapisuje go dla jednej maszyny. - Na końcu stderr dostaje podsumowanie: kod wyjścia i liczbę maszyn według sposobu zakończenia, a potem wiersz dla każdej maszyny w podanej kolejności. Wiersz podaje
donealbo kod wyjścia, jego rodzaj i przyczynę: błąd tutaj (dla 255 słowami samegossh) albo wierszError:polecenia. Maszyna, która po Ctrl-C nie potwierdziła zakończenia polecenia, ma staninterrupted, may still run.
Kod wyjścia kilku maszyn
Polecenie kończy się najgorszym kodem wyjścia spośród maszyn: 0, gdy każda maszyna zakończyła się kodem 0. W przeciwnym razie, od najgorszego:
- 130 — przerwanie, tutaj lub na maszynie.
- 1 — polecenie nie powiodło się na maszynie, co mogło zostawić ją częściowo zmienioną, niezależnie od kodu, którym się tam zakończyło.
- 255 — nie udało się połączyć z maszyną albo połączenie zostało zerwane.
- 3 — maszyna nie była w stanie, którego wymaga polecenie, albo nie może go uruchomić.
- 4 — na pytanie odpowiedziano „nie”.
Kod wyjścia 2 to błędny wiersz poleceń na tej maszynie, jak przy każdym poleceniu.
Wiersze JSON
Z --json stdout dostaje jeden wiersz dla każdej maszyny, gdy jej polecenie się zakończy, w kolejności zakończenia, i nic poza tym. Program czyta wiersze w miarę ich nadchodzenia.
{"host":"pi@vm1","state":"done","exit_code":0,"result":{...}}| Pole | Znaczenie |
|---|---|
host | maszyna tak, jak podaje ją --host lub plik hostów |
state | done: polecenie zakończyło się kodem 0. failed: zakończyło się tam innym kodem albo jego uruchomienie nie powiodło się tutaj. interrupted: uruchomienie zostało przerwane, a maszyna poinformowała, że polecenie się zakończyło. may_still_run: uruchomienie zostało przerwane tutaj, a maszyna nie poinformowała w czasie oczekiwania, że polecenie się zakończyło. not_started: uruchomienie zostało przerwane, zanim przyszła kolej na maszynę; nic tam nie działało. |
exit_code | jak polecenie zakończyło się na maszynie albo jak jego uruchomienie zakończyło się tutaj: 255, gdy nie udało się połączyć z maszyną lub połączenie zostało zerwane, 3, gdy maszyna nie może uruchomić polecenia, 130, gdy uruchomienie zostało przerwane. Inny kod, na przykład 137 po zabiciu procesu, to kod maszyny bez zmian, ze stanem failed. |
result | to, co polecenie zapisało z --json, tak jak opisuje to strona polecenia. Dla agent logs tablica jego wierszy; zachowywane jest najwyżej 16 MiB. Polecenie, które zapisuje wynik i kończy się kodem 1 (doctor, agent update), też ma to pole. |
error | dlaczego polecenie nie zakończyło się kodem 0, z kind i message: błąd uruchomienia tutaj (rodzaj ssh dla maszyny, z którą nie udało się połączyć, a komunikat kończy się słowami ssh w nawiasach), w przeciwnym razie obiekt błędu polecenia, a w przeciwnym razie obiekt utworzony z jego kodu wyjścia i ostatniego wiersza na stderr |
output | to, co polecenie zapisało na stdout, a co nie jest JSON; albo, gdy zapisało więcej niż 16 MiB, zdanie, które o tym informuje |
stderr zawiera wiersze maszyn, w tym własny wiersz Error: polecenia tam, gdzie polecenie zapisuje go z --json (agent update), oraz podsumowanie. Błędy uruchomień tutaj są tylko w wierszach na stdout.
# Maszyny, na których status nie zakończył się kodem 0
ironflock --hosts line3.txt status --json 2>/dev/null | jq -r 'select(.state != "done") | .host'Ctrl-C na kilku maszynach
Ctrl-C, SIGTERM lub SIGHUP kończy uruchomienia tak, jak kończy uruchomienie na jednej maszynie: każde polecenie na maszynie dostaje ten sygnał, a każda maszyna ma 15 sekund na potwierdzenie, że jej polecenie się zakończyło. Maszyna, która tego nie zrobi, ma stan may_still_run. Maszyny, na które jeszcze nie przyszła kolej, niczego nie uruchamiają. Podsumowanie wymienia je jako not started, a polecenie kończy się kodem 130.
Które polecenia działają na kilku maszynach
| Polecenia | Na kilku maszynach |
|---|---|
version, status, doctor, os images, os drives, agent restart, agent start | zawsze |
agent logs | zawsze; z --follow nie z --json, ponieważ wiersz maszyny przychodzi, gdy jej polecenie się zakończy, a --follow się nie kończy |
agent stop, agent update, agent configure, agent remove, os update, os rollback, self-update | z --yes: zadają pytanie, a na kilku maszynach jednocześnie nikt nie jest pytany |
completion | obsługiwane tutaj i na żadnej maszynie, tak jak --help |
agent install, os install, os flash, os reset | wcale: ich plik .flock opisuje jedno urządzenie albo wymazują dysk, nośnik lub dane urządzenia po pytaniu, które wskazuje jedną maszynę |
Flaga wskazująca plik na tej maszynie jest odrzucana przy kilku maszynach, ponieważ plik trafiłby na każdą maszynę: -c poleceń doctor i agent configure opisuje jedno urządzenie. Wyjątkiem jest --proxy-password-file polecenia agent configure, dla jednego konta proxy dla maszyn jednej lokalizacji.
Wiersz poleceń, który nie działa na kilku maszynach, kończy się kodem wyjścia 2 i podaje przyczynę, zanim plik hostów zostanie odczytany i zanim nastąpi połączenie z jakąkolwiek maszyną.