Fabric: 在Ubuntu 16.04主机上重启失败

创建于 2016-07-18  ·  21评论  ·  资料来源: fabric/fabric

内置的reboot()函数在Ubuntu 14.04和FreeBSD 10.x主机上均能正常运行,但在Ubuntu 16.04主机上已损坏。

在Ubuntu 14.04上发生了什么:
重新启动Fabric重新连接后,我收到这样的输出,并且系统重新启动。

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

在Ubuntu 16.04上发生了什么:

  1. 该命令根本没有输出。
  2. 系统实际上开始重新启动(Fabric中仍然没有输出)
  3. 系统完成重新启动,但是Fabric没有意识到,它没有重新连接,仍然没有输出。
  4. 布艺似乎永远坐在那里等着。

如果在这种状态下按Enter键,Fabric实际上会继续,但之前会显示此消息:

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

我正在使用以下代码重新启动:

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

最有用的评论

ubuntu错误https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1645002被标记为已在16.10中修复,但尚未在16.04中修复,并且尚不清楚何时修复。

对我来说,当前行为是paramiko / fabric立即检测到ssh连接已关闭,但是这是在paramiko / fabric看到重新启动命令完成之前。 至少它不会像原始报告中那样无限期地挂起。

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

Plain reboot()在针对AWS EC2和本地virtualbox VM的一系列测试中始终为我做到了这一点。 (我一直使用密钥文件身份验证。)

正如我建议的那样,我发现了一个简短而优雅的解决方法,上面没有太多详细信息:

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

这对我来说是预期的效果(在我针对AWS EC2和本地virtualbox VM进行的少数测试中,它们都运行了最新的ubuntu 16.04)。 请注意,“ shutdown -r now”的行为类似于“ reboot”,并且似乎不起作用。

我快速浏览了freebsd和openbsd手册页,看起来它们具有支持这些参数的shutdown命令。 我怀疑命令“ shutdown -r +0”几乎可以在所有“ reboot”的unix系统上使用。 因此可以考虑更改默认命令或更新文档。 (但是我很想先看到有关BSD系统的测试报告。)

所有21条评论

与run('reboot')完全相同

与手动run是不足为奇的-显然有关Ubuntu对重启,SSH连接等的处理有所变化。

没有什么明显的想法,但是reboot() (Fab的,不是Linux的)是非常基本的-它只是调用sudo('reboot') ,并临时调整Fabric的常规重新连接设置,这样它就可以在非平凡的重新启动序列之后进行重新连接(相对于默认设置,后者会很快放弃)。

参见https://github.com/fabric/fabric/blob/c0224a52df59821f21a8c0bd47ce15e42c2046a4/fabric/operations.py#L1244-您可能想要尝试进行调整。

另外,请尝试启用Paramiko的日志记录(请参阅疑难解答页面的底部-http://www.fabfile.org/troubleshooting.html),因为这可能会产生一些线索。

实际上,经过深思熟虑,听起来好像Ubuntu的reboot从未以某种方式从不退出或将退出代码提交给Fabric的执行处理程序( run / sudo ),因为您注意到sudo是在等待后将Enter混搭时变得生气的东西。

如果您查看reboot()代码,它期望sudo('reboot')调用最终会退出,因此它可以A)稍等一下,B)启动重新连接。

在Fabric的最后,执行只是在sudo中徘徊的事实,这意味着有些事情远非如此。 有点奇怪。 _也许_是Fabric本身的错误,但更像是远程的不良行为。 (PS:您在哪个织物版本上看到此信息?)

意外的想法-我们可以在timeout=上设置sudo ,然后在其周围设置except TimeoutException: pass 。 这样可以确保即使在这种(奇怪的)情况下,我们也默认尝试重新连接。

唯一的缺点是reboot实际上正在挂起并且系统没有真正地重新启动,但这不像我们通过上述更改使该情况变得更糟–无限挂起只会在这种情况下发生连接循环,而不是sudo

以下是Ubuntu 16.04中另一个非常奇怪的,已更改的行为。 当我在ssh会话中运行poweroff时,计算机确实关闭了电源,但是SSH会话挂起了! 无法使用Ctrl + C或Ctrl + D或任何其他方式。 我所能做的就是等待_lot_然后ssh中止:
packet_write_wait: Connection to 192.168.56.11: Broken pipe

我确实不十分了解SSH连接处理,但这可能与重新启动完全一样。

我刚刚遇到了严重的重启(AWS上的最新Ubuntu 16.04,Fabric == 1.12.0),但是使用了另一种方式。 对我来说,它只是抛出:

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

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

手动在终端中运行sudo reboot可以正常工作(主机重新启动)。

可能值得注意:

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

还有另一件事。 我将重新启动代码更改为使用aws-cli,并且在调用之后(大约需要1秒,似乎是异步的),我运行sudo('add-apt-repository --yes ppa:nginx/stable') 。 它一直都有效,但是现在在重新启动后,它也返回了-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"

然后,我尝试通过添加fabric.network.disconnect_all()来使结构重新连接。 结果导致要求输入密码(为什么?):

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

而且它仅在重启后添加了time.sleep(60 * 3)后才开始工作。 这显然是一个差劲的创可贴,现在我很困惑如何正确处理密码问题。 看起来与此问题有关。

问题似乎是在命令状态通过ssh连接返回之前,“重新引导”现在有时有时“太快”。

(提示:如果结果是处于冻结的ssh连接:键入\n~. aka enter,波浪号,句点。这是默认的ssh转义字符,然后是ssh的断开连接命令。如果您尝试ctrl- c或ctrl-d,ssh尝试将其传递给另一端运行的进程。)

一种解决方案是使用shutdown -r +1 ,它将在下一分钟安排重新启动,然后等待一分钟以使其重新启动,然后开始尝试重新连接。 诚然,等待一分钟并不是很好。

可以尝试的骇人听闻的东西: shutdown -r +0应该等效于reboot ,但是在我有限的对VirtualBox中运行的Ubuntu-16.04的测试中,它往往会花一秒钟的时间,显示下一个在断开手动ssh会话之前的shell提示。

这可能是#1444的重复

如果将初始化守护程序切换为新贵,则重新启动将按预期进行。 看来systemd立即杀死了sshd。

Debian / Ubuntu的systemd软件包中存在一个错误,该错误在关机时在SSH之前就杀死了网络服务,因此一切都挂起了。
它已固定在最新的发行版中。 不知道Ubuntu软件包的状态。

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

在某些脚本中,我还遇到了有关reboot()用法的问题。 我发现使用密码连接时,重新启动正常进行,但是使用密钥文件身份验证时,连接挂起(重新启动已完成)。

ubuntu错误https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1645002被标记为已在16.10中修复,但尚未在16.04中修复,并且尚不清楚何时修复。

对我来说,当前行为是paramiko / fabric立即检测到ssh连接已关闭,但是这是在paramiko / fabric看到重新启动命令完成之前。 至少它不会像原始报告中那样无限期地挂起。

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

Plain reboot()在针对AWS EC2和本地virtualbox VM的一系列测试中始终为我做到了这一点。 (我一直使用密钥文件身份验证。)

正如我建议的那样,我发现了一个简短而优雅的解决方法,上面没有太多详细信息:

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

这对我来说是预期的效果(在我针对AWS EC2和本地virtualbox VM进行的少数测试中,它们都运行了最新的ubuntu 16.04)。 请注意,“ shutdown -r now”的行为类似于“ reboot”,并且似乎不起作用。

我快速浏览了freebsd和openbsd手册页,看起来它们具有支持这些参数的shutdown命令。 我怀疑命令“ shutdown -r +0”几乎可以在所有“ reboot”的unix系统上使用。 因此可以考虑更改默认命令或更新文档。 (但是我很想先看到有关BSD系统的测试报告。)

shutdown -r +0对我们来说还不够。 由于重新启动不接受手动超时,因此我什至尝试了以下方法:

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

尽管挥舞着所有的手,但下一个命令会无限期地挂起。 连接池是否可能保持(并使用)死连接? 如果是这样,是否有解决方法? 我可以暂时减少连接级别的超时吗?

确实,您需要用reboot()的方式替换现有连接:

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

道歉以恢复旧的问题,我还可以确认在尝试重新启动LXC容器时发生此问题。 @ploxiln使用command="shutdown -r +0"确实对我们有用

在全新安装了bash的FreeBSD 11.1上确认此错误:

reboot(wait=1)结果:

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!

在结束@ ambsw-technology和@ploxiln注释后,我最终需要用它来使事情顺利进行。 我正在针对Ubuntu 16.04 LTS服务器(从Windows客户端)运行。

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

仅供参考,对于18.04.2 LTS服务器,我仍然看到了这一点。

有什么解决办法吗? 16.04也有问题

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

yuvadm picture yuvadm  ·  5评论

shadyabhi picture shadyabhi  ·  5评论

SamuelMarks picture SamuelMarks  ·  3评论

bitprophet picture bitprophet  ·  4评论

haydenflinner picture haydenflinner  ·  5评论