diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index 42114c7e9..92c68eca9 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -41,7 +41,7 @@ from moulinette import msettings, msignals, m18n from moulinette.core import init_authenticator from yunohost.utils.error import YunohostError from moulinette.utils.log import getActionLogger -from moulinette.utils.process import check_output +from moulinette.utils.process import check_output, call_async_output from moulinette.utils.filesystem import read_json, write_to_json from yunohost.app import app_fetchlist, app_info, app_upgrade, app_ssowatconf, app_list, _install_appslist_fetch_cron from yunohost.domain import domain_add, domain_list, _get_maindomain, _set_maindomain @@ -474,23 +474,54 @@ def tools_update(ignore_apps=False, ignore_packages=False): # "packages" will list upgradable packages packages = [] if not ignore_packages: - cache = apt.Cache() # Update APT cache + # LC_ALL=C is here to make sure the results are in english + command = "LC_ALL=C apt update" + # TODO : add @is_unit_operation to tools_update so that the + # debug output can be fetched when there's an issue... + callbacks = ( + # stdout goes to debug + lambda l: logger.debug(l.rstrip()), + # stderr goes to warning + # FIXME : filter the damn "CLI interface not stable" from apt >.> + lambda l: logger.warning(l.rstrip()), + ) + logger.info(m18n.n('updating_apt_cache')) - if not cache.update(): + + returncode = call_async_output(command, callbacks, shell=True) + + if returncode != 0: + + # TODO : here, we should run something like a + # `cat /etc/apt/sources.list /etc/apt/sources.list.d/*` + # and append it to the error message to improve debugging + raise YunohostError('update_cache_failed') - cache.open(None) - cache.upgrade(True) + # List upgradable packages + # LC_ALL=C is here to make sure the results are in english + upgradable_raw = check_output("LC_ALL=C apt list --upgradable") - # Add changelogs to the result - for pkg in cache.get_changes(): + # Dirty parsing of the output + upgradable_raw = [l.strip() for l in upgradable_raw.split("\n") if l.strip()] + for line in upgradable_raw: + # Remove stupid warning and verbose messages >.> + if "apt does not have a stable CLI interface" in line or "Listing..." in line: + continue + # line should look like : + # yunohost/stable 3.5.0.2+201903211853 all [upgradable from: 3.4.2.4+201903080053] + line = line.split() + if len(line) != 6: + logger.warning("Failed to parse this line : %s" % ' '.join(line)) + continue packages.append({ - 'name': pkg.name, - 'fullname': pkg.fullname, - 'changelog': pkg.get_changelog() + "name": line[0].split("/")[0], + "new_version": line[1], + "current_version": line[5].strip("]"), }) + logger.debug(m18n.n('done')) # "apps" will list upgradable packages