[Bug 1953135] [NEW] Incorrect symlink checking => Your python3 install is corrupted.
Nico Schlömer
1953135 at bugs.launchpad.net
Fri Dec 3 09:23:47 UTC 2021
Public bug reported:
This is related to https://bugs.launchpad.net/bugs/1825655.
When trying to upgrade to jammy, I got
```
Your python3 install is corrupted. Please fix the '/usr/bin/python3'
symlink.
```
Digging into the matter, it comes down to this symlink checker in `DistUpgradeController.py`:
```
import logging
from configparser import ConfigParser
import os
from configparser import NoOptionError
logging.basicConfig(filename='example.log', encoding='utf-8',
level=logging.DEBUG)
def _pythonSymlinkCheck():
""" sanity check that /usr/bin/python3 points to the default
python version. Users tend to modify this symlink, which
breaks stuff in obscure ways (Ubuntu #75557).
"""
logging.debug("_pythonSymlinkCheck run")
binaries_and_dirnames = [("python3", "python3")]
for binary, dirname in binaries_and_dirnames:
debian_defaults = '/usr/share/%s/debian_defaults' % dirname
if os.path.exists(debian_defaults):
config = ConfigParser()
with open(debian_defaults) as f:
config.read_file(f)
try:
expected_default = config.get('DEFAULT', 'default-version')
except NoOptionError:
logging.debug("no default version for %s found in '%s'" %
(binary, config))
return False
try:
fs_default_version = os.readlink('/usr/bin/%s' % binary)
except OSError as e:
logging.error("os.readlink failed (%s)" % e)
return False
if not fs_default_version in (expected_default, os.path.join('/usr/bin', expected_default)):
logging.debug("%s symlink points to: '%s', but expected is '%s' or '%s'" %
(binary, fs_default_version, expected_default, os.path.join('/usr/bin', expected_default)))
return False
return True
res = _pythonSymlinkCheck()
print(res)
```
Running it indeed returns `False` on my machine. The log gives the reason:
```
DEBUG:root:_pythonSymlinkCheck run
DEBUG:root:python3 symlink points to: '/etc/alternatives/python3', but expected is 'python3.9' or '/usr/bin/python3.9'
```
The symlink is not followed through.
Instead of `os.readlink`, you want to use `os.path.realpath`.
** Affects: ubuntu-release-upgrader (Ubuntu)
Importance: Undecided
Status: New
--
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to ubuntu-release-upgrader in
Ubuntu.
https://bugs.launchpad.net/bugs/1953135
Title:
Incorrect symlink checking => Your python3 install is corrupted.
Status in ubuntu-release-upgrader package in Ubuntu:
New
Bug description:
This is related to https://bugs.launchpad.net/bugs/1825655.
When trying to upgrade to jammy, I got
```
Your python3 install is corrupted. Please fix the '/usr/bin/python3'
symlink.
```
Digging into the matter, it comes down to this symlink checker in `DistUpgradeController.py`:
```
import logging
from configparser import ConfigParser
import os
from configparser import NoOptionError
logging.basicConfig(filename='example.log', encoding='utf-8',
level=logging.DEBUG)
def _pythonSymlinkCheck():
""" sanity check that /usr/bin/python3 points to the default
python version. Users tend to modify this symlink, which
breaks stuff in obscure ways (Ubuntu #75557).
"""
logging.debug("_pythonSymlinkCheck run")
binaries_and_dirnames = [("python3", "python3")]
for binary, dirname in binaries_and_dirnames:
debian_defaults = '/usr/share/%s/debian_defaults' % dirname
if os.path.exists(debian_defaults):
config = ConfigParser()
with open(debian_defaults) as f:
config.read_file(f)
try:
expected_default = config.get('DEFAULT', 'default-version')
except NoOptionError:
logging.debug("no default version for %s found in '%s'" %
(binary, config))
return False
try:
fs_default_version = os.readlink('/usr/bin/%s' % binary)
except OSError as e:
logging.error("os.readlink failed (%s)" % e)
return False
if not fs_default_version in (expected_default, os.path.join('/usr/bin', expected_default)):
logging.debug("%s symlink points to: '%s', but expected is '%s' or '%s'" %
(binary, fs_default_version, expected_default, os.path.join('/usr/bin', expected_default)))
return False
return True
res = _pythonSymlinkCheck()
print(res)
```
Running it indeed returns `False` on my machine. The log gives the reason:
```
DEBUG:root:_pythonSymlinkCheck run
DEBUG:root:python3 symlink points to: '/etc/alternatives/python3', but expected is 'python3.9' or '/usr/bin/python3.9'
```
The symlink is not followed through.
Instead of `os.readlink`, you want to use `os.path.realpath`.
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/ubuntu-release-upgrader/+bug/1953135/+subscriptions
More information about the foundations-bugs
mailing list