Fabric: Redémarrage interrompu sur les hôtes Ubuntu 16.04

Créé le 18 juil. 2016  ·  21Commentaires  ·  Source: fabric/fabric

La fonction intégrée reboot() , qui fonctionne parfaitement à la fois sur les hôtes Ubuntu 14.04 et FreeBSD 10.x, mais est cassée sur les hôtes Ubuntu 16.04.

Que se passe-t-il sur Ubuntu 14.04:
Je reçois une sortie comme celle-ci et le système redémarre, après le redémarrage de Fabric se reconnecte.

[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:

Que se passe-t-il sur Ubuntu 16.04:

  1. Il n'y a pas du tout de sortie de la commande.
  2. Le système commence réellement à redémarrer (toujours pas de sortie dans Fabric)
  3. Le système termine le redémarrage, mais Fabric ne s'en rend pas compte, il ne se reconnecte pas, toujours pas de sortie.
  4. Le tissu reste là, attendant apparemment pour toujours.

Si j'appuie sur la touche Entrée dans cet état, Fabric continue en fait, mais affiche ce message avant:

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

J'utilise ce code pour redémarrer:

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

Commentaire le plus utile

Le bogue ubuntu https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1645002 est marqué comme corrigé dans 16.10, mais pas encore dans 16.04, et on ne sait pas quand il le sera.

Le comportement actuel pour moi est que paramiko / fabric détecte instantanément que la connexion ssh a été fermée, mais c'est avant que paramiko / fabric ne voit la commande de redémarrage terminée. Au moins, il ne se bloque pas indéfiniment comme dans le rapport original.

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

Plain reboot() fait de manière cohérente pour moi dans une poignée de tests contre AWS EC2 et une machine virtuelle virtualbox locale. (J'ai toujours utilisé l'authentification par fichier de clés.)

J'ai trouvé une solution de contournement courte et élégante, comme je l'ai suggéré sans autant de détails ci-dessus:

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

Cela a fonctionné comme prévu pour moi (dans ma poignée de tests contre AWS EC2 et la machine virtuelle virtualbox locale, tous exécutant ubuntu 16.04 à jour). Notez que "shutdown -r now" se comporte comme "reboot" et ne semble pas fonctionner.

J'ai jeté un coup d'œil rapide aux pages de manuel freebsd et openbsd, et il semble qu'ils aient une commande d'arrêt qui prend en charge ces paramètres. Je soupçonne que la commande "shutdown -r +0" fonctionnerait pour pratiquement tous les systèmes Unix sur lesquels "reboot" fonctionnait. Il pourrait donc être envisagé de modifier la commande par défaut ou de mettre à jour la documentation. (Mais je serais intéressé de voir d'abord un rapport de test sur un système BSD.)

Tous les 21 commentaires

C'est exactement la même chose avec run ('reboot')

Il n'en va pas de même avec un manuel run - il est clair que quelque chose a changé concernant la gestion par Ubuntu du redémarrage, des connexions SSH, etc.

Rien d'évident ne me vient à l'esprit, mais reboot() (Fab's, pas Linux's) est assez basique - il appelle simplement sudo('reboot') , et modifie temporairement les paramètres généraux de reconnexion de Fabric afin qu'il puisse gérer la reconnexion après une séquence de redémarrage non triviale (par rapport à la valeur par défaut, qui abandonnerait assez rapidement).

Voir https://github.com/fabric/fabric/blob/c0224a52df59821f21a8c0bd47ce15e42c2046a4/fabric/operations.py#L1244 - vous voudrez peut-être essayer de peaufiner cela.

Essayez également d'activer la journalisation de Paramiko (voir en bas de notre page de dépannage - http://www.fabfile.org/troubleshooting.html) car cela pourrait donner un indice.

En fait, après réflexion, il semble que reboot Ubuntu ne quitte jamais ou ne soumet jamais un code de sortie aux gestionnaires d'exécution de Fabric ( run / sudo ), puisque vous notez que sudo est ce qui devient fou lorsque vous écrasez Enter après avoir attendu.

Si vous regardez le code reboot() , il s'attend à ce que l'appel sudo('reboot') se termine finalement, de sorte qu'il puisse A) attendre un peu et B) initier la reconnexion.

Le fait que, du côté de Fabric, l'exécution traîne simplement dans le sudo signifie que quelque chose à distance viole cette attente. Un peu étrange. _Peut-être_ un bogue dans Fabric lui-même, mais ressemble plus à un mauvais comportement à l'extrémité distante. (PS: sur quelle (s) version (s) de tissu voyez-vous cela?)

Pensée désinvolte - nous pourrions peut-être placer timeout= sur le sudo , puis except TimeoutException: pass autour de lui. Cela garantirait que même dans cette (étrange) situation, nous essayons par défaut une reconnexion.

Le seul inconvénient serait le cas où reboot est en fait suspendu et le système ne redémarre pas vraiment, mais ce n'est pas comme si nous ferions des choses pire dans ce cas par le changement ci-dessus - le blocage infini se produirait simplement sur la boucle de connexion au lieu de l'intérieur du sudo .

Un autre comportement vraiment étrange et modifié dans Ubuntu 16.04 est le suivant. Quand j'exécute poweroff dans une session ssh, la machine s'éteint, mais les sessions SSH se bloquent! Il n'y a aucun moyen de Ctrl + C, ou Ctrl + D, ou quoi que ce soit. Tout ce que je peux faire est d'attendre un _lot_ puis ssh s'interrompt avec:
packet_write_wait: Connection to 192.168.56.11: Broken pipe

Je ne suis vraiment pas dans les poches profondes de la gestion des connexions SSH, mais cela pourrait être exactement le même problème qu'avec le redémarrage.

Je viens de rencontrer un redémarrage interrompu (Ubuntu 16.04 à jour sur AWS, Fabric == 1.12.0) mais d'une manière différente. Pour moi, ça jette juste:

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

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

L'exécution manuelle de sudo reboot dans le terminal fonctionne (redémarrage de l'hôte).

Il peut être intéressant de noter:

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

Et une autre chose étrange. J'ai changé le code de redémarrage pour utiliser aws-cli et après son appel (qui prend ~ 1sec, semble être asynchrone) je lance sudo('add-apt-repository --yes ppa:nginx/stable') . Cela a toujours fonctionné, mais maintenant après le redémarrage, il a également renvoyé -1:

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"

Ensuite, j'ai essayé de créer un tissu pour se reconnecter en ajoutant fabric.network.disconnect_all() . Cela a conduit à demander un mot de passe (pourquoi ??):

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

Et cela n'a commencé à fonctionner qu'après avoir ajouté par exemple time.sleep(60 * 3) après le redémarrage. Ce qui est évidemment un mauvais pansement, et maintenant je ne sais pas comment gérer correctement le problème de mot de passe. Il semble que cela soit lié à ce problème.

Le problème semble être que "redémarrer" est maintenant parfois "trop ​​rapide", avant que l'état de la commande ne revienne sur la connexion ssh.

(Astuce: Si vous êtes à une connexion ssh gelée en conséquence: tapez \n~. aka enter, tilde, point. C'est le caractère d'échappement ssh par défaut, puis la commande de déconnexion pour ssh. Si vous essayez simplement ctrl- c ou ctrl-d, ssh essaie de transmettre cela au processus en cours d'exécution de l'autre côté.)

Une solution consiste à utiliser shutdown -r +1 , qui planifiera le redémarrage pour la minute suivante, puis attendra une minute pour qu'il démarre, puis recommencera à essayer de se reconnecter. Certes, attendre une minute n'est pas génial.

Une chose hacky à essayer: shutdown -r +0 devrait être équivalent à reboot , mais dans mes tests limités d'Ubuntu-16.04 fonctionnant dans VirtualBox, cela a tendance à donner une fraction de seconde de plus, montrant le suivant shell juste avant de déconnecter une session ssh manuelle.

c'est probablement un dup de # 1444

Si le démon init est commuté sur upstart, le redémarrage fonctionne comme prévu. Il semble que systemd tue sshd immédiatement.

Il y avait un bogue sur le paquet Debian / Ubuntu de systemd qui, à l'arrêt, a tué le service réseau avant celui de SSH donc tout se bloque.
Il a été corrigé dans la dernière version intermédiaire. Je ne connais pas l'état du package Ubuntu.

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

J'ai également eu des problèmes concernant l'utilisation de reboot () dans certains de mes scripts. J'ai découvert que lors de la connexion avec un mot de passe, le redémarrage fonctionnait correctement, mais lors de l'utilisation de l'authentification par fichier de clés, la connexion a été interrompue (un redémarrage a été effectué).

Le bogue ubuntu https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1645002 est marqué comme corrigé dans 16.10, mais pas encore dans 16.04, et on ne sait pas quand il le sera.

Le comportement actuel pour moi est que paramiko / fabric détecte instantanément que la connexion ssh a été fermée, mais c'est avant que paramiko / fabric ne voit la commande de redémarrage terminée. Au moins, il ne se bloque pas indéfiniment comme dans le rapport original.

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

Plain reboot() fait de manière cohérente pour moi dans une poignée de tests contre AWS EC2 et une machine virtuelle virtualbox locale. (J'ai toujours utilisé l'authentification par fichier de clés.)

J'ai trouvé une solution de contournement courte et élégante, comme je l'ai suggéré sans autant de détails ci-dessus:

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

Cela a fonctionné comme prévu pour moi (dans ma poignée de tests contre AWS EC2 et la machine virtuelle virtualbox locale, tous exécutant ubuntu 16.04 à jour). Notez que "shutdown -r now" se comporte comme "reboot" et ne semble pas fonctionner.

J'ai jeté un coup d'œil rapide aux pages de manuel freebsd et openbsd, et il semble qu'ils aient une commande d'arrêt qui prend en charge ces paramètres. Je soupçonne que la commande "shutdown -r +0" fonctionnerait pour pratiquement tous les systèmes Unix sur lesquels "reboot" fonctionnait. Il pourrait donc être envisagé de modifier la commande par défaut ou de mettre à jour la documentation. (Mais je serais intéressé de voir d'abord un rapport de test sur un système BSD.)

shutdown -r +0 ne nous suffit pas. Étant donné que le redémarrage n'accepte pas un délai d'expiration manuel, j'ai même essayé quelque chose comme:

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

Malgré tout ce geste de la main, la commande suivante est suspendue indéfiniment. Est-il possible que le pool de connexions conserve (et utilise) la connexion morte? Si tel est le cas, existe-t-il une solution de contournement? Puis-je réduire temporairement le délai d'expiration au niveau de la connexion?

En effet, vous devez remplacer la connexion existante, comme le fait reboot() :

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

Toutes mes excuses pour raviver un ancien problème, je peux également confirmer que ce problème se produit lors de la tentative de redémarrage d'un conteneur LXC. La suggestion de @ploxiln d'utiliser command="shutdown -r +0" a fonctionné pour nous.

Confirmation de cette erreur sur une nouvelle installation de FreeBSD 11.1 avec bash installé:

reboot(wait=1) donne:

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!

J'ai fini par en avoir besoin pour faire avancer les choses après avoir réédité les commentaires @ ambsw-technology et @ploxiln . Je cours contre un serveur ubuntu 16.04 LTS (à partir d'un client Windows).

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

Pour info, je vois toujours cela contre les serveurs LTS 18.04.2.

Une solution pour ça? obtenir également un problème avec 16.04

Cette page vous a été utile?
0 / 5 - 0 notes