Fabric: Neustart auf Ubuntu 16.04-Hosts unterbrochen

Erstellt am 18. Juli 2016  ·  21Kommentare  ·  Quelle: fabric/fabric

Die eingebaute reboot() -Funktion, die sowohl auf Ubuntu 14.04- als auch auf FreeBSD 10.x-Hosts einwandfrei funktioniert hat, auf Ubuntu 16.04-Hosts jedoch nicht funktioniert.

Was passiert unter Ubuntu 14.04:
Ich erhalte eine solche Ausgabe und das System wird neu gestartet, nachdem Fabric den Neustart wieder hergestellt hat.

[ubuntu] out:
[ubuntu] out:
[ubuntu] out: Broadcast message from root<strong i="9">@ubuntu</strong>
[ubuntu] out:
[ubuntu] out:   (/dev/pts/0) at 15:02 ...
[ubuntu] out:
[ubuntu] out:
[ubuntu] out:
[ubuntu] out:
[ubuntu] out: The system is going down for reboot NOW!
[ubuntu] out:
[ubuntu] out:

Was passiert unter Ubuntu 16.04:

  1. Der Befehl gibt überhaupt keine Ausgabe aus.
  2. Das System startet tatsächlich einen Neustart (immer noch keine Ausgabe in Fabric).
  3. Das System beendet den Neustart, aber Fabric merkt es nicht, es verbindet sich nicht erneut, es gibt immer noch keine Ausgabe.
  4. Stoff sitzt einfach da und wartet scheinbar für immer.

Wenn ich in diesem Zustand die Eingabetaste drücke, fährt Fabric tatsächlich fort, zeigt jedoch die folgende Meldung an:

No handlers could be found for logger "paramiko.transport"
Warning: sudo() received nonzero return code -1 while executing 'reboot'!

Ich verwende diesen Code für einen Neustart:

def reboot_():
    with settings(warn_only=True):
        print 'rebooting'
        start_time = time.time()
        reboot(wait=1200)
        print 'reboot took: {} seconds'.format(time.time() - start_time)
Bug Core Needs investigation

Hilfreichster Kommentar

Der Ubuntu-Fehler https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1645002 ist in 16.10, aber noch nicht in 16.04 als behoben markiert und unklar, wann er auftreten wird.

Das aktuelle Verhalten für mich ist, dass paramiko / Fabric sofort erkennt, dass die SSH-Verbindung geschlossen wurde, aber bevor paramiko / Fabric sieht, dass der Neustartbefehl abgeschlossen ist. Zumindest hängt es nicht auf unbestimmte Zeit wie im ursprünglichen Bericht.

Fatal error: sudo() received nonzero return code -1 while executing!
...
Aborting.

Plain reboot() dies in einer Handvoll Tests gegen AWS EC2 und eine lokale Virtualbox-VM konsequent für mich getan. (Ich habe immer die Schlüsseldatei-Authentifizierung verwendet.)

Ich habe eine kurze und elegante Problemumgehung gefunden, wie ich oben ohne so viele Details vorgeschlagen habe:

reboot(command="shutdown -r +0")

Das hat für mich wie erwartet funktioniert (in meinen wenigen Tests gegen AWS EC2 und die lokale Virtualbox-VM, die alle mit Ubuntu 16.04 auf dem neuesten Stand sind). Beachten Sie, dass sich "shutdown -r now" wie "reboot" verhielt und nicht zu funktionieren schien.

Ich habe mir die Manpages freebsd und openbsd kurz angesehen, und es sieht so aus, als hätten sie einen Befehl zum Herunterfahren, der diese Parameter unterstützt. Ich vermute, dass der Befehl "shutdown -r +0" für so ziemlich jedes Unix-System funktioniert, auf dem "Neustart" funktioniert hat. Es könnte also in Betracht gezogen werden, den Standardbefehl zu ändern oder die Dokumentation zu aktualisieren. (Aber ich wäre interessiert, zuerst einen Bericht über einen Test auf einem BSD-System zu sehen.)

Alle 21 Kommentare

Genau so ist es mit run ('reboot')

Dasselbe gilt für ein Handbuch run ist nicht überraschend - es hat sich eindeutig etwas geändert, was Ubuntus Umgang mit Neustart, SSH-Verbindungen usw. betrifft.

Nichts Offensichtliches fällt mir ein, aber reboot() (Fabs, nicht Linux's) ist ziemlich einfach - es ruft einfach sudo('reboot') und ändert vorübergehend die allgemeinen Wiederverbindungseinstellungen von Fabric, damit die Wiederverbindung nach einer nicht trivialen Neustartsequenz verarbeitet werden kann (im Vergleich zum Standard, der ziemlich schnell aufgeben würde).

Siehe https://github.com/fabric/fabric/blob/c0224a52df59821f21a8c0bd47ce15e42c2046a4/fabric/operations.py#L1244 - möglicherweise möchten Sie versuchen, dies zu optimieren.

Versuchen Sie auch, die Protokollierung von Paramiko zu aktivieren (siehe unten auf unserer Seite zur Fehlerbehebung - http://www.fabfile.org/troubleshooting.html), da dies möglicherweise einen Hinweis liefert.

Auf den zweiten Blick klingt es tatsächlich so, als würde Ubuntus reboot niemals einen Exit-Code beenden oder an die Ausführungshandler von Fabric senden ( run / sudo ), da Sie feststellen, dass sudo wird wütend, wenn Sie Enter nach dem Warten zerdrücken.

Wenn Sie sich den Code reboot() ansehen, wird erwartet, dass der Aufruf von sudo('reboot') irgendwann beendet wird, sodass er A) etwas warten und B) die erneute Verbindung einleiten kann.

Die Tatsache, dass die Ausführung von Fabric nur innerhalb der sudo bedeutet, dass etwas aus der Ferne gegen diese Erwartung verstößt. Irgendwie seltsam. Möglicherweise ein Fehler in Fabric selbst, fühlt sich aber eher nach schlechtem Verhalten auf der Remote-Seite an. (PS: Auf welchen Stoffversionen sehen Sie das?)

Nebenbei gedacht - wir könnten vielleicht timeout= auf die sudo , dann except TimeoutException: pass darum herum. Dies würde sicherstellen, dass wir auch in dieser (seltsamen) Situation standardmäßig versuchen, eine erneute Verbindung herzustellen.

Der einzige Nachteil wäre der Fall, in dem reboot tatsächlich hängt und das System nicht wirklich neu startet, aber es ist nicht so, als würden wir durch die obige Änderung die Dinge für diesen Fall noch schlimmer machen - das unendliche Hängen würde einfach passieren die Verbindungsschleife anstelle von sudo .

Ein anderes wirklich seltsames, geändertes Verhalten in Ubuntu 16.04 ist das folgende. Wenn ich poweroff in einer SSH-Sitzung ausführe, schaltet sich der Computer aus, aber die SSH-Sitzungen hängen! Es gibt keine Möglichkeit zu Strg + C oder Strg + D oder irgendetwas. Alles was ich tun kann ist eine Menge zu warten, dann bricht ssh ab mit:
packet_write_wait: Connection to 192.168.56.11: Broken pipe

Ich bin wirklich nicht in den tiefen Taschen der SSH-Verbindungsbehandlung, aber dies könnte genau das gleiche Problem sein wie beim Neustart.

Ich bin gerade auf einen fehlerhaften Neustart gestoßen (aktuelles Ubuntu 16.04 unter AWS, Fabric == 1.12.0), aber auf eine andere Art und Weise. Für mich wirft es nur:

Fatal error: sudo() received nonzero return code -1 while executing!

Requested: reboot
Executed: sudo -S -p 'sudo password:'  /bin/bash -l -c "reboot"

Das manuelle Ausführen von sudo reboot im Terminal funktioniert (Neustart des Hosts).

Kann erwähnenswert sein:

$ readlink /sbin/reboot 
/bin/systemctl
$ readlink /sbin/shutdown
/bin/systemctl

Und noch eine seltsame Sache. Ich habe den Neustartcode geändert, um aws-cli zu verwenden, und nach dem Aufruf (der ~ 1 Sekunde dauert, scheint asynchron zu sein) führe ich sudo('add-apt-repository --yes ppa:nginx/stable') . Es hat immer funktioniert, aber jetzt nach dem Neustart gab es auch -1 zurück:

sudo: add-apt-repository --yes ppa:nginx/stable

Fatal error: sudo() received nonzero return code -1 while executing!

Requested: add-apt-repository --yes ppa:nginx/stable
Executed: sudo -S -p 'sudo password:'  /bin/bash -l -c "add-apt-repository --yes ppa:nginx/stable"

Dann habe ich versucht, Stoff zum Wiederverbinden zu bringen, indem ich fabric.network.disconnect_all() hinzugefügt habe. Es wurde ein Passwort angefordert (warum ??):

[...] sudo: add-apt-repository --yes ppa:nginx/stable
[...] Login password for 'ubuntu': 

Und es fing erst an zu funktionieren, nachdem ich nach dem Neustart zB time.sleep(60 * 3) hinzugefügt hatte. Das ist offensichtlich ein schlechtes Pflaster, und jetzt bin ich verwirrt, wie ich mit dem Passwortproblem richtig umgehen soll. Sieht so aus, als ob es mit diesem Problem zusammenhängt.

Das Problem scheint zu sein, dass "Neustart" jetzt manchmal "zu schnell" ist, bevor der Status des Befehls über die SSH-Verbindung wiederhergestellt wird.

(Tipp: Wenn Sie als Ergebnis eine eingefrorene SSH-Verbindung haben: Geben Sie \n~. aka enter, tilde, period ein. Dies ist das Standard-Escapezeichen ssh, dann der Befehl zum Trennen von ssh. Wenn Sie nur Strg- versuchen c oder ctrl-d, ssh versucht, dies an den auf der anderen Seite laufenden Prozess zu übergeben.)

Eine Lösung besteht darin, shutdown -r +1 , wodurch der Neustart für die nächste Minute geplant wird. Warten Sie dann eine Minute, bis der Neustart gestartet ist, und versuchen Sie dann erneut, eine Verbindung herzustellen. Zugegeben, eine Minute zu warten ist nicht so toll.

Ein Hacky-Versuch: shutdown -r +0 sollte reboot , aber in meinen begrenzten Tests von Ubuntu-16.04, das in VirtualBox ausgeführt wird, dauert es in der Regel einen Bruchteil einer Sekunde länger und zeigt den nächsten Shell-Eingabeaufforderung kurz vor dem Trennen einer manuellen SSH-Sitzung.

Dies ist wahrscheinlich ein Dup von # 1444

Wenn der Init-Daemon auf Upstart umgeschaltet wird, funktioniert der Neustart wie erwartet. Es sieht so aus, als würde systemd sshd sofort töten.

Es gab einen Fehler im Systemd-Paket von Debian / Ubuntu, der beim Herunterfahren den Netzwerkdienst vor dem SSH-Dienst beendet hat, sodass alles hängen bleibt.
Es wurde auf der neuesten Punktversion behoben. Ich weiß nichts über den Status des Ubuntu-Pakets.

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=751636

Ich hatte auch Probleme mit der Verwendung von reboot () in einigen meiner Skripte. Ich fand heraus, dass der Neustart beim Herstellen einer Verbindung mit einem Kennwort ordnungsgemäß funktionierte, bei Verwendung der Schlüsseldateiauthentifizierung jedoch die Verbindung unterbrochen wurde (und der Neustart wurde durchgeführt).

Der Ubuntu-Fehler https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1645002 ist in 16.10, aber noch nicht in 16.04 als behoben markiert und unklar, wann er auftreten wird.

Das aktuelle Verhalten für mich ist, dass paramiko / Fabric sofort erkennt, dass die SSH-Verbindung geschlossen wurde, aber bevor paramiko / Fabric sieht, dass der Neustartbefehl abgeschlossen ist. Zumindest hängt es nicht auf unbestimmte Zeit wie im ursprünglichen Bericht.

Fatal error: sudo() received nonzero return code -1 while executing!
...
Aborting.

Plain reboot() dies in einer Handvoll Tests gegen AWS EC2 und eine lokale Virtualbox-VM konsequent für mich getan. (Ich habe immer die Schlüsseldatei-Authentifizierung verwendet.)

Ich habe eine kurze und elegante Problemumgehung gefunden, wie ich oben ohne so viele Details vorgeschlagen habe:

reboot(command="shutdown -r +0")

Das hat für mich wie erwartet funktioniert (in meinen wenigen Tests gegen AWS EC2 und die lokale Virtualbox-VM, die alle mit Ubuntu 16.04 auf dem neuesten Stand sind). Beachten Sie, dass sich "shutdown -r now" wie "reboot" verhielt und nicht zu funktionieren schien.

Ich habe mir die Manpages freebsd und openbsd kurz angesehen, und es sieht so aus, als hätten sie einen Befehl zum Herunterfahren, der diese Parameter unterstützt. Ich vermute, dass der Befehl "shutdown -r +0" für so ziemlich jedes Unix-System funktioniert, auf dem "Neustart" funktioniert hat. Es könnte also in Betracht gezogen werden, den Standardbefehl zu ändern oder die Dokumentation zu aktualisieren. (Aber ich wäre interessiert, zuerst einen Bericht über einen Test auf einem BSD-System zu sehen.)

shutdown -r +0 reicht uns nicht. Da der Neustart keine manuelle Zeitüberschreitung akzeptiert, habe ich sogar Folgendes versucht:

try:
    sudo("shutdown -r +0", timeout=300)
except NetworkError:
    pass
# in case the sudo times out during reboot
sleep(15)

Trotz all dieser Handbewegung hängt der nächste Befehl auf unbestimmte Zeit. Ist es möglich, dass der Verbindungspool an der toten Verbindung festhält (und diese verwendet)? Wenn ja, gibt es eine Problemumgehung? Kann ich das Timeout auf Verbindungsebene vorübergehend reduzieren?

In der Tat müssen Sie die vorhandene Verbindung wie bei reboot() ersetzen:

https://github.com/fabric/fabric/blob/1.13.2/fabric/operations.py#L1289 -L1294

Ich entschuldige mich für die Wiederbelebung eines alten Problems und kann auch bestätigen, dass dieses Problem auftritt, wenn versucht wird, einen LXC-Container neu zu starten. @ploxilns Vorschlag, command="shutdown -r +0" hat bei uns funktioniert.

Bestätigen dieses Fehlers bei einer Neuinstallation von FreeBSD 11.1 mit installiertem Bash:

reboot(wait=1) ergibt:

Fatal error: sudo() received nonzero return code -1 while executing!

Requested: reboot
Executed: sudo -S -p 'sudo password:'  /usr/local/bin/bash -l -c "reboot"

Aborting.
Traceback (most recent call last):
…
    raise env.abort_exception(msg)
hosts.FabricException: sudo() received nonzero return code -1 while executing!

Ich brauchte dies, um die Dinge in Gang zu bringen, nachdem ich @ ambsw-Technologie und @ ploxiln Kommentare

sudo('shutdown -r +0')
time.sleep(30)
fabric.state.connections.connect(env.host_string)

Zu Ihrer Information, ich sehe dies immer noch gegen 18.04.2 LTS-Server.

Irgendeine Lösung dafür? auch bekommen Problem mit 16.04

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen