解决Ubuntu无法打开"Software & Updates"的问题

Posted on | 1728 words | ~4 mins
Linux Ubuntu

最近发现我的Ubuntu服务器的"Software & Updates"无法打开。网上有各种解决方案,“不幸”的是没一个能起作用,“幸运”的是答案大方向是对的。最终结合一些诊断手段解决了该问题。像这种网上给个大概方向,然后结合自身状况,进一步诊断和解决问题的模式,应该是日常工作中的常态。本文分享一下这个过程。

Ubuntu服务器"Software & Updates"无法打开是指:

  • 通过应用搜索找到"Software & Updates"或者"Settings->About->Software Updates"(见下图的位置),点击按钮会没有任何反应。

software_&_updates

  • 如果在"Terminal"里执行sudo software-properties-gtk,会有错误信息:
 1ERROR:dbus.proxies:Introspect error on :1.239:/: dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoReply: Message recipient disconnected from message bus without replying
 2Traceback (most recent call last):
 3  File "/usr/bin/software-properties-gtk", line 100, in <module>
 4    app = SoftwarePropertiesGtk(datadir=options.data_dir, options=options, file=file)
 5  File "/usr/lib/python3/dist-packages/softwareproperties/gtk/SoftwarePropertiesGtk.py", line 222, in __init__
 6    self.backend.Reload();
 7  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 72, in __call__
 8    return self._proxy_method(*args, **keywords)
 9  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 141, in __call__
10    return self._connection.call_blocking(self._named_service,
11  File "/usr/lib/python3/dist-packages/dbus/connection.py", line 652, in call_blocking
12    reply_message = self.send_message_with_reply_and_block(
13dbus.exceptions.DBusException: org.freedesktop.DBus.Error.ServiceUnknown: The name :1.239 was not provided by any .service files

网上搜索dbus.exceptions.DBusException: org.freedesktop.DBus.Error.ServiceUnknown能看到不少相关解答。比如Ubuntu 18.04 software-properties-gtk failing with org.freedesktop.DBus.Error.ServiceUnknown,再比如Software & Updates won’t launch at all,还有App “Software & Updates” not responding。尝试后,均不能解决我的问题,但是能得到一些确定性的提示:

  • software-properties-gtk通过系统dbus执行
  • 通过sudo journalctl -u dbus -b可以查看dbus日志(注意:sudo十分重要,因为查看的是系统服务dbus的日志),从而发现导致software-properties-gtk失败的原因
  • 失败原因是某些python包“不正常”导致software-properties-gtk找不到requests_unixsocket(见如下日志片段)
1Traceback (most recent call last):
2  File "/usr/lib/software-properties/software-properties-dbus", line 68, in <module>
3    server = SoftwarePropertiesDBus(bus, datadir=datadir)
4  File "/lib/python3/dist-packages/softwareproperties/dbus/SoftwarePropertiesDBus.py", line 66, in __init__
5    self._livepatch_service = LivepatchService()
6  File "/lib/python3/dist-packages/softwareproperties/LivepatchService.py", line 93, in __init__
7    self._session = requests_unixsocket.Session()
8NameError: name 'requests_unixsocket' is not defined

网上答案推荐重新安装相关python包,例如:sudo apt install --reinstall python3-six python3-certifi python3-requests python3-idna。显然,我的操作系统有问题的包不是这几个,所以操作后依旧不能让requests-unixsocket被正常import。根据手上信息,我的目标就很明确了,找到实际损坏的包,重新安装。于是用sudo vim /lib/python3/dist-packages/softwareproperties/LivepatchService.py查看这个文件到底是如何importrequests-unixsocket。发现最开始的地方,尝试import requests_unixsocket,而导致失败的异常被try-except“吞掉了”。

1try:
2    import dateutil.parser
3    import requests_unixsocket
4
5    gi.require_version('Snapd', '1')
6    from gi.repository import Snapd
7except(ImportError, ValueError):
8    pass

于是我直接修改该文件,在except捕捉到异常后,打印相关信息

1except(ImportError, ValueError):
2    import traceback
3    print(traceback.format_exc())

再次运行sudo software-properties-gtk,失败后查看日志,终于发现是因为urllib3有问题:

 1    import requests_unixsocket
 2  File "/lib/python3/dist-packages/requests_unixsocket/__init__.py", line 1, in <module>
 3    import requests
 4  File "/lib/python3/dist-packages/requests/__init__.py", line 43, in <module>
 5    import urllib3
 6ModuleNotFoundError: No module named 'urllib3'
 7Traceback (most recent call last):
 8  File "/usr/lib/software-properties/software-properties-dbus", line 68, in <module>
 9    server = SoftwarePropertiesDBus(bus, datadir=datadir)
10  File "/lib/python3/dist-packages/softwareproperties/dbus/SoftwarePropertiesDBus.py", line 66, in __init__
11    self._livepatch_service = LivepatchService()
12  File "/lib/python3/dist-packages/softwareproperties/LivepatchService.py", line 96, in __init__
13    self._session = requests_unixsocket.Session()
14NameError: name 'requests_unixsocket' is not defined

重新安装sudo apt install --reinstall python3-urllib3再运行,这回日志显示chardet有问题:

 1    import requests_unixsocket
 2  File "/lib/python3/dist-packages/requests_unixsocket/__init__.py", line 1, in <module>
 3    import requests
 4  File "/lib/python3/dist-packages/requests/__init__.py", line 44, in <module>
 5    import chardet
 6ModuleNotFoundError: No module named 'chardet'
 7Traceback (most recent call last):
 8  File "/usr/lib/software-properties/software-properties-dbus", line 68, in <module>
 9    server = SoftwarePropertiesDBus(bus, datadir=datadir)
10  File "/lib/python3/dist-packages/softwareproperties/dbus/SoftwarePropertiesDBus.py", line 66, in __init__
11    self._livepatch_service = LivepatchService()
12  File "/lib/python3/dist-packages/softwareproperties/LivepatchService.py", line 96, in __init__
13    self._session = requests_unixsocket.Session()
14NameError: name 'requests_unixsocket' is not defined

继续sudo apt install --reinstall python3-chardet,再执行终于看到了期待依旧的窗口:

software_&_updates

最后,简要总结一下这个问题解决的两个关键点:

  • 通过搜索了解到:software-properties-gtk启动失败是由于python包有问题
  • 通过修改源码,打印import导致的异常,找到有问题的python

最后的最后:try-except没事别吞异常,会导致程序无法运行的异常至少记条日志