diff --git a/backend/SystemUpdater/Core/DataAcquisition.py b/backend/SystemUpdater/Core/DataAcquisition.py index 57840b1..7082707 100644 --- a/backend/SystemUpdater/Core/DataAcquisition.py +++ b/backend/SystemUpdater/Core/DataAcquisition.py @@ -18,8 +18,8 @@ import datetime import threading from email import message -from binascii import a2b_hex from datetime import datetime +from binascii import a2b_hex from Crypto.PublicKey import RSA from urllib import parse, request from PyQt5.QtCore import QSettings @@ -104,7 +104,7 @@ class UpdateMsgCollector(): self.upgrade_list = [] self.waitSendList = [] self.cache = None - + self.Send_log = False self.updateManager = manager # 转换 & 加密 self.convertor = FormatConvert(self) @@ -189,22 +189,23 @@ class UpdateMsgCollector(): logging.error(e) def Upgrade_Process_Msg(self, action, dict_msg = {}): - tmp_dict = {} - tmp_dict.update(dict_msg) - try: - self.UpdateInfos.update({"step":self.action_map.get(action, "")}) - if self.upgrade_mode == self.MODE_INSTALL_SYSTEM: - self.UpdateInfos.update({"appname":"Upgrade System"}) - tmp_dict.update(self.UpdateInfos) - json_file = json.dumps(tmp_dict.copy()) - self.UpdateMsg(self.messageType_map.get(action, ""), json_file, self.uuid) - else: - tmp_dict.update(self.UpdateInfos) - json_file = json.dumps(tmp_dict.copy()) - self.UpdateMsg(self.messageType_map.get(action, ""), json_file, self.uuid) - except Exception as e: - logging.error(e) - tmp_dict.clear() + if self.Send_log == True: + tmp_dict = {} + tmp_dict.update(dict_msg) + try: + self.UpdateInfos.update({"step":self.action_map.get(action, "")}) + if self.upgrade_mode == self.MODE_INSTALL_SYSTEM: + self.UpdateInfos.update({"appname":"Upgrade System"}) + tmp_dict.update(self.UpdateInfos) + json_file = json.dumps(tmp_dict.copy()) + self.UpdateMsg(self.messageType_map.get(action, ""), json_file, self.uuid) + else: + tmp_dict.update(self.UpdateInfos) + json_file = json.dumps(tmp_dict.copy()) + self.UpdateMsg(self.messageType_map.get(action, ""), json_file, self.uuid) + except Exception as e: + logging.error(e) + tmp_dict.clear() def make_background_version(self,pkg): if pkg.is_installed == True: @@ -217,6 +218,9 @@ class UpdateMsgCollector(): self.UploadMessage = {} self.PackageInfo = {} self.UpdateInfos = {} + + def _set_Send_log(self, flag): + self.Send_log = flag class FormatConvert(): def __init__(self, DataCollector): @@ -549,7 +553,8 @@ class PHPServer(threading.Thread): if os.path.isfile(log_file_gzip): os.remove(log_file_gzip) -def PHPSeverSend(_appname="", _appversion="", _statue="", _errorcode=""): +def PHPSeverSend(_send_log = False, _appname="", _appversion="", _statue="", _errorcode=""): + if _send_log == True: send_thread = PHPServer() send_thread.get_values(_appname=_appname, _appversion=_appversion, _state=_statue, _errorcode=_errorcode) send_thread.start() diff --git a/backend/SystemUpdater/Core/Database.py b/backend/SystemUpdater/Core/Database.py index b1e0671..f7cd2e1 100644 --- a/backend/SystemUpdater/Core/Database.py +++ b/backend/SystemUpdater/Core/Database.py @@ -29,7 +29,14 @@ class Sqlite3Server(object): # uncoverable配置文件 self.ucconfigs = UpgradeConfig(datadir = "/etc/kylin-version", name = "kylin-system-version.conf") self._system_version_config() - + + #发送日志 + self.upload_upgrade_log = self.window_main.configs_uncover.getWithDefault("SystemStatus", "upload_upgrade_log", False) + if self.upload_upgrade_log == False: + logging.warning("Log sending is not enabled, and the server will not receive your update records .") + else: + self.window_main.collector._set_Send_log(self.upload_upgrade_log) + # 初始化连接数据库 def init_sqlit(self): logging.info(_("Initialize the connection to the database ...")) @@ -211,7 +218,7 @@ class Sqlite3Server(object): self._refresh_system_version(version) #FIXME: 临时方案 PHP - PHPSeverSend(_appname=pkgname, _appversion=pkgversion, _statue=status, _errorcode="10000100") + PHPSeverSend(_send_log = self.upload_upgrade_log, _appname=pkgname, _appversion=pkgversion, _statue=status, _errorcode="10000100") elif pkg_list: # 单包更新 # 获取单包数据插入数据库 pkgname = pkg_list.pop(0) @@ -261,7 +268,7 @@ class Sqlite3Server(object): # 软件商店获取中文名 appname_cn = self.get_cn_appname(str(pkgname)) #FIXME: 临时方案 PHP - PHPSeverSend(_appname=pkgname, _appversion=pkgversion, _statue=status, _errorcode="10000100") + PHPSeverSend(_send_log = self.upload_upgrade_log, _appname=pkgname, _appversion=pkgversion, _statue=status, _errorcode="10000100") try: self.insert_into_updateinfo(pkgname, pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn) # FIXME: 发送插入数据库成功的信号local_upgrade_list @@ -314,7 +321,7 @@ class Sqlite3Server(object): self.insert_into_updateinfo(str(i), pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn) self.window_main.dbusController.UpdateSqlitSingle(str(i), timestr) #FIXME: 临时方案 PHP - PHPSeverSend(_appname=pkg.name, _appversion=pkgversion, _statue=status, _errorcode="10000100") + PHPSeverSend(_send_log = self.upload_upgrade_log, _appname=pkg.name, _appversion=pkgversion, _statue=status, _errorcode="10000100") # insert group deb next for i in pkg_group: # FIXME: 获取组信息 @@ -336,7 +343,7 @@ class Sqlite3Server(object): InstallInfos.update({"errorCode":str(error_string+" "+error_desc)}) self.window_main.collector.Upgrade_Process_Msg("finish-install", InstallInfos.copy()) #FIXME: 临时方案 PHP - PHPSeverSend(_appname=i, _appversion=pkgversion, _statue=status, _errorcode="10000100") + PHPSeverSend(_send_log = self.upload_upgrade_log, _appname=i, _appversion=pkgversion, _statue=status, _errorcode="10000100") try: self.insert_into_updateinfo(str(i), pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn) self.window_main.dbusController.UpdateSqlitSingle(str(i), timestr) diff --git a/backend/SystemUpdater/Core/UpdateList.py b/backend/SystemUpdater/Core/UpdateList.py index 90ce3cb..c3ea878 100644 --- a/backend/SystemUpdater/Core/UpdateList.py +++ b/backend/SystemUpdater/Core/UpdateList.py @@ -57,7 +57,7 @@ class UpdateList(): for base in data_dirs.split(':')] if self.parent.options.close_filter == False and self.parent.source_info.is_disc == False and \ - self.parent.configs.getWithDefault("SystemStatus", "close_source_filter", False) == False : + self.parent.configs_cover.getWithDefault("SystemStatus", "close_source_filter", False) == False : #开启原过滤 self.close_filter = False self.fu = UpdateListFilterCache(self.parent) @@ -472,7 +472,7 @@ class UpdateList(): #important_list 为空时此次不需要升级 if not group_important_list and not self.upgrade_meta.single_pkgs: - self.parent.dbusController.DistUpdateDetectFinished(True,[],'','') + self.parent.dbusController.UpdateDetectFinished(True,[''],'','') return #产生单包的JSON @@ -483,7 +483,7 @@ class UpdateList(): self._make_autoupgrade_config(cache,self.upgrade_meta,self.upgrade_meta.adjust_pkgs) - self.parent.dbusController.DistUpdateDetectFinished(True,self.upgrade_meta.upgrade_groups + self.upgrade_meta.single_pkgs,'','') + self.parent.dbusController.UpdateDetectFinished(True,self.upgrade_meta.upgrade_groups + self.upgrade_meta.single_pkgs,'','') return diff --git a/backend/SystemUpdater/Core/UpdaterConfigParser.py b/backend/SystemUpdater/Core/UpdaterConfigParser.py index 7adbd8f..771d80c 100755 --- a/backend/SystemUpdater/Core/UpdaterConfigParser.py +++ b/backend/SystemUpdater/Core/UpdaterConfigParser.py @@ -52,8 +52,9 @@ class UpgradeConfig(SafeConfigParser): logging.error("Error: setValue section:%s option:%s value:%s",section, option, value) logging.error(str(e)) return False + ddd = self.config_files[-1] if is_write == True: - with open(self.config_files[0], 'w+') as configfile: + with open(self.config_files[-1], 'w+') as configfile: self.write(configfile) return True @@ -91,7 +92,7 @@ class UpgradeConfig(SafeConfigParser): logging.error(str(e)) return if is_write == True: - with open(self.config_files[0], 'w+') as configfile: + with open(self.config_files[-1], 'w+') as configfile: self.write(configfile) def getListFromFile(self, section, option): diff --git a/backend/SystemUpdater/Core/enums.py b/backend/SystemUpdater/Core/enums.py index 874bb97..dd4c0e0 100644 --- a/backend/SystemUpdater/Core/enums.py +++ b/backend/SystemUpdater/Core/enums.py @@ -3,11 +3,12 @@ """enums - Enumerates for apt daemon dbus messages""" __all__ = ( + "ERROR_UPDATE_DEFAULT_FAILED", "ERROR_UPDATE_SOURCE_FAILED","ERROR_NETWORK_FAILED","ERROR_NOT_GROUPS_CONFIG","ERROR_SOFTWARE_INDEX_RROKEN", "ERROR_NOT_INIT_PACKAGESINFIO","ERROR_READ_IMPORTANTLIST_FAILED","ERROR_RESOLVER_FAILED","ERROR_NOT_UPGRADE_PACKAGES", "ERROR_REMOVE_ESSENTIAL_PACKAGES","ERROR_NOT_DISK_SPACE", - "ERROR_UPDATE_KEY_SIGNATURES", + "ERROR_UPDATE_KEY_SIGNATURES","ERROR_UPDATE_NET_AUTHENTICATION","ERROR_UPDATE_NOTREAD_SOURCES","PRIORITY_UPGRADE_SUCCCESSED", "get_error_description_from_enum", "get_error_string_from_enum", "get_source_name_from_enum") @@ -16,21 +17,19 @@ gettext.bindtextdomain('kylin-system-updater', '/usr/share/locale') gettext.textdomain('kylin-system-updater') _ = gettext.gettext +PRIORITY_UPGRADE_SUCCCESSED = "priority-upgrade-successed" + #更新阶段 +ERROR_UPDATE_DEFAULT_FAILED = "error-update-default-failed" ERROR_UPDATE_KEY_SIGNATURES = "The following signatures" +ERROR_UPDATE_NET_AUTHENTICATION ="does the network require authentication?" +ERROR_UPDATE_NOTREAD_SOURCES = "The list of sources could not be read" - -#UPGRADE MONITOR STATUS -MONIT_DETECT = "step-updatedetect" -MONIT_DEPRESOLUT = "step-depresolution" -MONIT_DOWNLOAD = "step-downloading" -MONIT_INSTALL = "step-installing" -MONIT_FINISH = "step-finish" - -#自己的 ERROR_UPDATE_SOURCE_FAILED = "error-update-source-failed" ERROR_NETWORK_FAILED = "error-network-failed" ERROR_NOT_GROUPS_CONFIG = "error-not-groups-config" + +#自己的 ERROR_SOFTWARE_INDEX_RROKEN = "error-software-index-broken" ERROR_NOT_INIT_PACKAGESINFIO = "error-not-init-packagesinfo" ERROR_READ_IMPORTANTLIST_FAILED = "error-read-importantlist-failed" @@ -39,38 +38,57 @@ ERROR_NOT_UPGRADE_PACKAGES = "error-not-upgrade-packages" ERROR_REMOVE_ESSENTIAL_PACKAGES = "error-remove-essential-packages" ERROR_NOT_DISK_SPACE = "error-not-disk-space" - -_DESCS_ERROR = { - ERROR_UPDATE_SOURCE_FAILED: _("Check your source management server config"), - ERROR_NETWORK_FAILED: _("Please check your network connection and retry."), - ERROR_NOT_GROUPS_CONFIG: _("groups JSON ConfigPkgs install failed"), - ERROR_NOT_INIT_PACKAGESINFIO: _("An unresolvable problem occurred while " - "initializing the package information.\n\n" - "Please report this bug against the 'kylin-system-updater' " - "package and include the following error " - "message:\n"), - ERROR_SOFTWARE_INDEX_RROKEN: _("It is impossible to install or remove any software. " - "Please use the package manager \"Synaptic\" or run " - "\"sudo apt-get install -f\" in a terminal to fix " - "this issue at first."), - ERROR_READ_IMPORTANTLIST_FAILED: _("tttttttttttttttttt"), - ERROR_RESOLVER_FAILED: _("nothing"), - ERROR_NOT_UPGRADE_PACKAGES: _("This update cannot detect the upgradeable package."), - ERROR_REMOVE_ESSENTIAL_PACKAGES: _("You request the removal of a system-essential package."), - ERROR_NOT_DISK_SPACE: _("test")} - _STRINGS_ERROR = { - ERROR_UPDATE_SOURCE_FAILED: _("Unable to access the source management server"), - ERROR_NETWORK_FAILED: _("Please check your network connection and retry."), - ERROR_NOT_GROUPS_CONFIG: _("Unable to get group configuration package, please contact administrator to solve"), - ERROR_SOFTWARE_INDEX_RROKEN: _("Software index is broken"), - ERROR_NOT_INIT_PACKAGESINFIO: _("Could not initialize the package information"), - ERROR_READ_IMPORTANTLIST_FAILED: _("read important list failed"), + PRIORITY_UPGRADE_SUCCCESSED: _("Update Manager upgrade is complete, please restart the control panel before performing the system update"), + + #update + ERROR_UPDATE_DEFAULT_FAILED: _("Check for update exceptions,please check your network connection and retry."), + ERROR_UPDATE_SOURCE_FAILED: ERROR_UPDATE_DEFAULT_FAILED, + ERROR_NETWORK_FAILED: ERROR_UPDATE_DEFAULT_FAILED, + ERROR_NOT_GROUPS_CONFIG: ERROR_UPDATE_DEFAULT_FAILED, + ERROR_UPDATE_KEY_SIGNATURES: ERROR_UPDATE_DEFAULT_FAILED, + ERROR_READ_IMPORTANTLIST_FAILED: ERROR_UPDATE_DEFAULT_FAILED, + ERROR_SOFTWARE_INDEX_RROKEN: ERROR_UPDATE_DEFAULT_FAILED, + ERROR_NOT_INIT_PACKAGESINFIO: ERROR_UPDATE_DEFAULT_FAILED, + + #install ERROR_RESOLVER_FAILED: _("Could not calculate the upgrade"), ERROR_NOT_UPGRADE_PACKAGES: _("There is an exception in the update package."), ERROR_REMOVE_ESSENTIAL_PACKAGES: _("There is an exception in the update package."), ERROR_NOT_DISK_SPACE: _("Disk space is insufficient, please clean the disk and then upgrade")} +_DESCS_ERROR = { + #update + ERROR_UPDATE_SOURCE_FAILED: _("Unable to access the source management server"), + ERROR_NETWORK_FAILED: _("Please check your network connection and retry."), + ERROR_UPDATE_KEY_SIGNATURES: _("Check your source public key signature"), + ERROR_UPDATE_NOTREAD_SOURCES: _("Please check your source list and retry."), + ERROR_UPDATE_NET_AUTHENTICATION: _("Check if your network requires authentication?"), + ERROR_NOT_GROUPS_CONFIG: _("Unable to get group configuration package, please contact administrator to solve."), + ERROR_NOT_INIT_PACKAGESINFIO: _("An unresolvable problem occurred while " + "initializing the package information.\n\n" + "Please report this bug against the 'kylin-system-updater' " + "package and include the following error " + "message:\n"), + ERROR_SOFTWARE_INDEX_RROKEN: _("Software index is broken") + _("It is impossible to install or remove any software. " + "Please use the package manager \"Synaptic\" or run " + "\"sudo apt-get install -f\" in a terminal to fix " + "this issue at first."), + ERROR_READ_IMPORTANTLIST_FAILED: _("read important list failed"), + + #install + ERROR_RESOLVER_FAILED: _("nothing"), + ERROR_NOT_UPGRADE_PACKAGES: _("This update cannot detect the upgradeable package."), + ERROR_REMOVE_ESSENTIAL_PACKAGES: _("You request the removal of a system-essential package."), + ERROR_NOT_DISK_SPACE: _("test") + } + +#UPGRADE MONITOR STATUS +MONIT_DETECT = "step-updatedetect" +MONIT_DEPRESOLUT = "step-depresolution" +MONIT_DOWNLOAD = "step-downloading" +MONIT_INSTALL = "step-installing" +MONIT_FINISH = "step-finish" SOURCE_NAME = { 'kylin-installer':_("Kylin Installer"), diff --git a/backend/SystemUpdater/Core/utils.py b/backend/SystemUpdater/Core/utils.py index 8395409..fbbaabc 100644 --- a/backend/SystemUpdater/Core/utils.py +++ b/backend/SystemUpdater/Core/utils.py @@ -660,43 +660,6 @@ def get_package_label(pkg): name = getattr(pkg.candidate, "summary", "") return capitalize_first_word(name) -#安装时禁止关机 进行加锁 -def LockedPreventShutdown(): - global inhibit_lock - """ - Send a dbus signal to logind to not suspend the system, it will be - released when the return value drops out of scope - """ - try: - from gi.repository import Gio, GLib - connection = Gio.bus_get_sync(Gio.BusType.SYSTEM) - - var, fdlist = connection.call_with_unix_fd_list_sync( - 'org.freedesktop.login1', '/org/freedesktop/login1', - 'org.freedesktop.login1.Manager', 'Inhibit', - GLib.Variant('(ssss)', - ('shutdown', - 'Kylin System Updater', 'Installing Packages', - 'block')), - None, 0, -1, None, None) - inhibit_lock = Gio.UnixInputStream(fd=fdlist.steal_fds()[var[0]]) - logging.info("Shutdown Has been locked...") - except Exception as e: - logging.error(e) - -#解锁禁止关机 -def unLockedEnableShutdown(): - global inhibit_lock - try: - if inhibit_lock != None: - inhibit_lock.close() - logging.info("Shutdown Has been unlocked...") - inhibit_lock == None - else: - logging.info("Not locked and Quitting ...") - except Exception as e: - logging.error("unlock failed." + str(e)) - # 查看uu进程是否需要kill def kill_process(path): try: diff --git a/backend/SystemUpdater/UpdateManager.py b/backend/SystemUpdater/UpdateManager.py index 6278a30..4b8a11f 100644 --- a/backend/SystemUpdater/UpdateManager.py +++ b/backend/SystemUpdater/UpdateManager.py @@ -1,8 +1,6 @@ # UpdateManager.py # -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*- import os -import subprocess -from apt import Cache import apt_pkg import sys import time @@ -11,10 +9,16 @@ import dbus import logging import dbus.service import json +import threading +import subprocess +from apt import Cache +from gettext import gettext as _ from apt.debfile import DebPackage from dbus.mainloop.glib import DBusGMainLoop DBusGMainLoop(set_as_default=True) +from .Core.errors import * +from .Core.enums import * from .Core.MyCache import MyCache from .UpdateManagerDbus import UpdateManagerDbusController,UPDATER_DBUS_INTERFACE,UPDATER_DBUS_PATH,UPDATER_DBUS_SERVICE from .Core.UpdateList import UpdateList @@ -23,14 +27,12 @@ from .Core.Database import Sqlite3Server from .Core.loop import mainloop from .Core.DataAcquisition import UpdateMsgCollector -from gettext import gettext as _ from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig from SystemUpdater.Core.utils import get_broken_details,kill_process from SystemUpdater.Core.DpkgInstallProgress import LogInstallProgress from SystemUpdater.Core.utils import deb_verify,PolicyKit_Authority,get_proc_from_dbus_name -from .Core.errors import * -from .Core.enums import * + class UpdateManager(): BACKEND_PKG_NAME = 'kylin-system-updater' @@ -51,24 +53,27 @@ class UpdateManager(): self.dbusController = self._setup_dbus() #配置文件 - self.configs = UpgradeConfig("/var/lib/kylin-system-updater/") + self.configs_uncover = UpgradeConfig("/var/lib/kylin-system-updater/",defaults_dir="system-updater-defaults.conf") + self.configs_cover = UpgradeConfig("system-updater-coverable.conf") + self.uuconfigs = UpgradeConfig(datadir = "/var/lib/unattended-upgrades/", name = "unattended-upgrades-policy.conf") + #数据采集器 + self.collector = UpdateMsgCollector(self) + #连接数据库 self.sqlite3_server = Sqlite3Server(self) #是否重启apt self.init_config_aptdeamon = False - #数据采集器 - self.collector = UpdateMsgCollector(self) - #后台aptdaemon的语言环境 self.aptdaemonLang = os.environ["LANGUAGE"] #失败后重启进行安装的限制次数 目前在自适应升级上面使用 self.retry_limit = self.RETRY_LIMIT_NUM + self.simulate_mode = SimulateTerminal() #光盘源 self.source_info = UpdateSourceInfo() @@ -77,9 +82,13 @@ class UpdateManager(): self.install_mode = UpdateInstallMode(self) self.apt_p2p_config = AptP2pConfigManager() - #加载Cache - self.refresh_cache() + + self.inhibit_shutdown = InhibitShutdownLock() + self._reload_options_config() + #加载Cache + self._refresh_cache_only() + def _reload_options_config(self): #添加默认保留旧配置 @@ -131,6 +140,8 @@ class UpdateManager(): if self.init_config_aptdeamon == True: self.init_config_aptdeamon = False self.dbusController.make_aptdeamon_restart() + #重启的话等待重启完成 + time.sleep(0.5) # self.dbusController.set_aptdeamon_environ("init","config") def run(self): @@ -196,7 +207,7 @@ class UpdateManager(): def start_update(self,update_mode = InstallBackend.MODE_UPDATE_ALL): try: #每次更新之前 重新读取配置文件 刷新参数 - self.configs.reReadConfigFiles() + self.configs_cover.reReadConfigFiles() self.check_config_patch() self.retry_limit = self.RETRY_LIMIT_NUM @@ -213,20 +224,27 @@ class UpdateManager(): if self.options.no_update_source is False: self.dbusController.on_update_important_list() + return #不进行update if self.options.no_update: self.start_available() return + self.start_update_backend(update_mode = update_mode) + + except UpdateBaseError as excep: + self.dbusController.UpdateDetectFinished(False,[''],excep.header,excep.desc) + except UpdateProgressExit: + pass + except Exception as e: + logging.error(e) + + def start_update_backend(self,update_mode = InstallBackend.MODE_UPDATE_ALL): + try: #调用aptdeamon进行update update_backend = get_backend(self, InstallBackend.ACTION_UPDATE,update_mode) update_backend.start() - - except UpdateBaseError as excep: - self.dbusController.DistUpdateDetectFinished(False,[],excep.header,excep.desc) - except UpdateProgressExit: - pass except Exception as e: logging.error(e) @@ -238,8 +256,8 @@ class UpdateManager(): self.update_list = UpdateList(self) #1、 检查出现安装过程异常重启 出现的话 进行异常修复 - if self.configs.getWithDefault("SystemStatus", "abnormal_reboot", False) == True: - self.configs.setValue("SystemStatus","abnormal_reboot",str(False),True) + if self.configs_uncover.getWithDefault("SystemStatus", "abnormal_reboot", False) == True: + self.configs_uncover.setValue("SystemStatus","abnormal_reboot",str(False),True) logging.warning("start fix Abnormal Reboot broken pkgs...") self.start_fix_broken() return @@ -256,7 +274,7 @@ class UpdateManager(): self.cache.clear() except UpdateBaseError as excep: - self.dbusController.DistUpdateDetectFinished(False,[],excep.header,excep.desc) + self.dbusController.UpdateDetectFinished(False,[''],excep.header,excep.desc) except UpdateProgressExit as excep: pass except Exception as e: @@ -277,97 +295,76 @@ class UpdateManager(): logging.error(str(e)) raise UpdateBaseError(ERROR_NOT_INIT_PACKAGESINFIO) + def _refresh_cache_only(self): + try: + #第一次进入 之后update不进入 + if self.cache is None: + self.cache = MyCache(None) + else: + self.cache.open(None) + self.cache._initDepCache() + except Exception as e: + logging.error(e) + def _check_self_upgrade(self,cache): need_upgrade = False - + self_upgrade = [] with open(UpdateList.IMPORTANT_LIST_PATH, 'r') as f: data = f.read() important_list = data.split() - #self - if self.BACKEND_PKG_NAME in cache: - self_pkg = cache[self.BACKEND_PKG_NAME] - #是否安装 - if self_pkg.is_installed and self_pkg.is_upgradable: - logging.info("Check: Updater(%s) start upgrading From %s to %s...",self.BACKEND_PKG_NAME,\ - self_pkg.installed.source_version,self_pkg.candidate.source_version) - if self.BACKEND_PKG_NAME in important_list: - self_pkg.mark_install() - need_upgrade = True - else: - logging.info("Check: Updater(%s:%s) No need to upgrade...",self.BACKEND_PKG_NAME,self_pkg.installed.source_version) - else: - logging.info("Check: Updater(%s:%s) No need to upgrade...",self.BACKEND_PKG_NAME,self_pkg.installed.source_version) - else: - #没有在cache中就认为不需要升级 - logging.error("Check: Updater(%s) The upgrade package is not in Cache...",self.BACKEND_PKG_NAME) - - #Aptdaemon - if self.APTD_PKG_NAME in cache: - self_pkg = cache[self.APTD_PKG_NAME] - #是否安装 - if self_pkg.is_installed and self_pkg.is_upgradable: - logging.info("Check: Aptdaemon(%s) start upgrading From %s to %s...",self.APTD_PKG_NAME,\ - self_pkg.installed.source_version,self_pkg.candidate.source_version) - if self.BACKEND_PKG_NAME in important_list: - self_pkg.mark_install() - need_upgrade = True - else: - logging.info("Check: Aptdaemon(%s:%s) No need to upgrade...",self.APTD_PKG_NAME,self_pkg.installed.source_version) - else: - logging.info("Check: Aptdaemon(%s:%s) No need to upgrade...",self.APTD_PKG_NAME,self_pkg.installed.source_version) - else: - #没有在cache中就认为不需要升级 - logging.error("Check: Aptdaemon(%s) The upgrade package is not in Cache...",self.APTD_PKG_NAME) - - #控制面板前端包的检查升级 - if self.FRONTEND_PKG_NAME in cache: - self_pkg = cache[self.FRONTEND_PKG_NAME] - - if self_pkg.is_installed: - #是否可升级 - if self_pkg.is_upgradable: - logging.info("Check: Frontend(%s) start upgrading From %s to %s...",self.FRONTEND_PKG_NAME,\ + for pkg_name in (self.BACKEND_PKG_NAME,self.APTD_PKG_NAME,self.FRONTEND_PKG_NAME): + if pkg_name in cache: + self_pkg = cache[pkg_name] + if self_pkg.is_installed and self_pkg.is_upgradable: + logging.info("Check: (%s) will upgrading From %s to %s...",pkg_name,\ self_pkg.installed.source_version,self_pkg.candidate.source_version) - if self.FRONTEND_PKG_NAME in important_list: - self_pkg.mark_install() - need_upgrade = True + if pkg_name in important_list: + try: + logging.info("Check: (%s) start upgrading From %s to %s...",pkg_name,\ + self_pkg.installed.source_version,self_pkg.candidate.source_version) + self_pkg.mark_install() + self_upgrade.append(pkg_name) + need_upgrade = True + except SystemError: + logging.error("Check: mark %s to upgrade Failed...",pkg_name) else: - logging.info("Check: Frontend(%s:%s) No need to upgrade...",self.FRONTEND_PKG_NAME,self_pkg.installed.source_version) + logging.info("Check: (%s:%s) No need to upgrade and duo to not pust...",pkg_name,self_pkg.installed.source_version) else: - logging.info("Check: Frontend(%s:%s) No need to upgrade...",self.FRONTEND_PKG_NAME,self_pkg.installed.source_version) + logging.info("Check: (%s:%s) No need to upgrade...",pkg_name,self_pkg.installed.source_version) else: - self.dbusController.UpdateDetectStatusChanged(95,_("Group configuration being updated")) - logging.info("Check: Frontend(%s) start new installing...",self.FRONTEND_PKG_NAME) - self_pkg.mark_install() - need_upgrade = True - else: - #没有在cache中就认为不需要升级 - logging.error("Check: Frontend(%s) The upgrade package is not in Cache...",self.FRONTEND_PKG_NAME) - + logging.error("Check: (%s) The upgrade package is not in Cache...",pkg_name) + + #config包 if self.GROUPS_PKG_NAME in cache: pkg_json = cache[self.GROUPS_PKG_NAME] - #是否安装 if pkg_json.is_installed: - #是否可升级 if pkg_json.is_upgradable: self.dbusController.UpdateDetectStatusChanged(95,_("Group configuration being updated")) logging.info("Check: groups JSON ConfigPkgs(%s) start upgrading From %s to %s...",self.GROUPS_PKG_NAME,\ pkg_json.installed.source_version,pkg_json.candidate.source_version) - pkg_json.mark_install() - need_upgrade = True + try: + pkg_json.mark_install() + self_upgrade.append(self.GROUPS_PKG_NAME) + need_upgrade = True + except SystemError: + logging.error("Check: mark %s to upgrade Failed...",pkg_name) else: logging.info("Check: ConfigPkgs(%s:%s) No need to upgrade...",self.GROUPS_PKG_NAME,pkg_json.installed.source_version) else: self.dbusController.UpdateDetectStatusChanged(95,_("Group configuration being updated")) logging.info("Check: groups JSON ConfigPkgs(%s) start new installing...",self.GROUPS_PKG_NAME) - pkg_json.mark_install() - need_upgrade = True + try: + pkg_json.mark_install() + self_upgrade.append(self.GROUPS_PKG_NAME) + need_upgrade = True + except SystemError: + logging.error("Check: mark %s to upgrade Failed...",pkg_name) else: raise UpdateBaseError(ERROR_NOT_GROUPS_CONFIG) if need_upgrade == True: - self.start_install(InstallBackend.MODE_INSTALL_SINGLE,True) + self.start_install(InstallBackend.MODE_INSTALL_SINGLE,True,upgrade_content=self_upgrade) raise UpdateProgressExit() def _check_system_broken(self,cache): @@ -875,6 +872,89 @@ class AptP2pConfigManager(): self.p2pConfigs.setValue("apt_p2p_Khashmir","BOOTSTRAP",str(value)) +class InhibitShutdownLock(): + + def __init__(self): + self.inhibit_lock = None + + #安装时禁止关机 进行加锁 + def lock(self): + """ + Send a dbus signal to logind to not suspend the system, it will be + released when the return value drops out of scope + """ + try: + from gi.repository import Gio, GLib + connection = Gio.bus_get_sync(Gio.BusType.SYSTEM) + + var, fdlist = connection.call_with_unix_fd_list_sync( + 'org.freedesktop.login1', '/org/freedesktop/login1', + 'org.freedesktop.login1.Manager', 'Inhibit', + GLib.Variant('(ssss)', + ('shutdown', + 'Kylin System Updater', 'Installing Packages', + 'block')), + None, 0, -1, None, None) + self.inhibit_lock = Gio.UnixInputStream(fd=fdlist.steal_fds()[var[0]]) + logging.info("Shutdown Has been locked...") + except Exception as e: + logging.error(e) + + #解锁禁止关机 + def unlock(self): + try: + if self.inhibit_lock != None: + self.inhibit_lock.close() + self.inhibit_lock == None + logging.info("Shutdown Has been unlocked...") + else: + logging.info("Not locked and Quitting ...") + except Exception as e: + logging.error("unlock failed." + str(e)) + +class SimulateTerminal(): + ZH_UNMET_DEPENDENCIES = '下列软件包有未满足的依赖关系:' + EN_UNMET_DEPENDENCIES = 'The following packages have unmet dependencies:' + def __init__(self): + pass + + def _emulate_install(self,pkgs): + args = ["apt-get", "install","--simulate"] + args = args + pkgs + + p = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True) + logging.info(str(p.stdout)) + return p.stdout + + def emulate_update(self): + args = ["apt-get", "update"] + + p = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True) + logging.info(str(p.stdout)) + return p.stdout + + def thread_install(self): + threading_emulate = threading.Thread(target=self._emulate_install) + threading_emulate.start() + + def thread_update(self): + threading_emulate = threading.Thread(target=self.emulate_update) + threading_emulate.start() + + def dependencies_broken(self,pkgs): + terminal_msg = self._emulate_install(pkgs) + + if len(terminal_msg) > 500: + terminal_msg = '' + if self.ZH_UNMET_DEPENDENCIES in terminal_msg: + terminal_msg = '\n' + self.ZH_UNMET_DEPENDENCIES + terminal_msg.split(self.ZH_UNMET_DEPENDENCIES)[1] + elif self.EN_UNMET_DEPENDENCIES in terminal_msg: + terminal_msg = '\n' + self.EN_UNMET_DEPENDENCIES + terminal_msg.split(self.EN_UNMET_DEPENDENCIES)[1] + else: + terminal_msg = '' + + return terminal_msg + class UpdateInstallMode(): def __init__(self,parent): self.parent = parent @@ -960,20 +1040,20 @@ class UpdateInstallMode(): "PrepareForShutdown", prepare_for_shutdown_handler) def auto_install(self): - return self.parent.configs.getWithDefault("InstallMode", "auto_install", False) + return self.parent.configs_uncover.getWithDefault("InstallMode", "auto_install", False) def manual_install(self): - return self.parent.configs.getWithDefault("InstallMode", "manual_install", False) + return self.parent.configs_uncover.getWithDefault("InstallMode", "manual_install", False) def shutdown_mode(self): - return self.parent.configs.getWithDefault("InstallMode", "shutdown_install", False) + return self.parent.configs_uncover.getWithDefault("InstallMode", "shutdown_install", False) def set_shutdown_install(self,status=False): - self.parent.configs.setValue("InstallMode","manual_install",str(status)) + self.parent.configs_uncover.setValue("InstallMode","manual_install",str(status)) def reset_shutdown_mode(self): self.tmp_content = [] - self.parent.configs.setValue("InstallMode","manual_install",str(False)) + self.parent.configs_uncover.setValue("InstallMode","manual_install",str(False)) #释放锁 更新完成时重新那锁 if self.inhibit_lock != None: @@ -981,8 +1061,8 @@ class UpdateInstallMode(): self.inhibit_lock = None def install_finished(self): - self.parent.configs.setValue("InstallMode","manual_install",str(False)) - self.parent.configs.setValue("InstallMode","auto_install",str(False)) + self.parent.configs_uncover.setValue("InstallMode","manual_install",str(False)) + self.parent.configs_uncover.setValue("InstallMode","auto_install",str(False)) self._prompt_in_boot() diff --git a/backend/SystemUpdater/UpdateManagerDbus.py b/backend/SystemUpdater/UpdateManagerDbus.py index 34f1843..3e9c855 100755 --- a/backend/SystemUpdater/UpdateManagerDbus.py +++ b/backend/SystemUpdater/UpdateManagerDbus.py @@ -11,7 +11,7 @@ from .Core.loop import mainloop from .Core.errors import * from .Core.enums import * from .Core.utils import humanize_size -from SystemUpdater.Core.utils import unLockedEnableShutdown,get_proc_from_dbus_name,PolicyKit_Authority +from SystemUpdater.Core.utils import get_proc_from_dbus_name,PolicyKit_Authority import locale from xml.etree import ElementTree from .Core.MyCache import MyCache @@ -58,19 +58,24 @@ class UpdateManagerDbusController(dbus.service.Object): self.transaction = None + def _update_important_reply(self,retval): + if bool(retval) == False: + self.UpdateDetectFinished(False,[''],get_error_string_from_enum(ERROR_UPDATE_SOURCE_FAILED),\ + get_error_description_from_enum(ERROR_UPDATE_SOURCE_FAILED)) + else: + self.parent.start_update_backend() + + def _update_important_error(self,retval): + logging.error(str(retval)) + self.UpdateDetectFinished(False,[''],get_error_string_from_enum(ERROR_UPDATE_SOURCE_FAILED),\ + get_error_description_from_enum(ERROR_UPDATE_SOURCE_FAILED)) + #更新important.list的本次升级的列表 def on_update_important_list(self): - try: - self.UpdateDetectStatusChanged(10,_("Updating Source Template")) - obj = self.bus.get_object('com.kylin.software.properties', '/com/kylin/software/properties') - interface = dbus.Interface(obj, dbus_interface='com.kylin.software.properties.interface') - retval = interface.updateSourceTemplate(timeout=20) - except Exception as excep: - raise UpdateBaseError(ERROR_UPDATE_SOURCE_FAILED, - details= str(excep)) - if retval == False: - raise UpdateBaseError(ERROR_UPDATE_SOURCE_FAILED) - return + self.UpdateDetectStatusChanged(10,_("Updating Source Template")) + obj = self.bus.get_object('com.kylin.software.properties', '/com/kylin/software/properties') + interface = dbus.Interface(obj, dbus_interface='com.kylin.software.properties.interface') + interface.updateSourceTemplate(timeout=20,reply_handler=self._update_important_reply,error_handler=self._update_important_error) def is_reboot_required(self): """If a reboot is required to get all changes into effect.""" @@ -127,11 +132,7 @@ class UpdateManagerDbusController(dbus.service.Object): """Request a shutdown of the daemon.""" #如果在下载就请求 取消 self.CancelDownload() - try: - #尝试接触 关闭枷锁 - unLockedEnableShutdown() - except: - logging.error("File lock release failure") + self.parent.inhibit_shutdown.unlock() logging.info("Quitting was requested") logging.debug("Quitting main loop...") mainloop.quit() @@ -152,8 +153,8 @@ class UpdateManagerDbusController(dbus.service.Object): def SetConfigValue(self,section, option, value): try: logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' SetConfigValue ...') - if self.parent.configs.has_section(str(section)) and self.parent.configs.has_option(str(section),str(option)): - if self.parent.configs.setValue(str(section), str(option),str(value)) == True: + if self.parent.configs_uncover.has_section(str(section)) and self.parent.configs_uncover.has_option(str(section),str(option)): + if self.parent.configs_uncover.setValue(str(section), str(option),str(value)) == True: return True else: return False @@ -170,8 +171,12 @@ class UpdateManagerDbusController(dbus.service.Object): @dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='ss',out_signature='bs') def GetConfigValue(self,section, option): try: - if self.parent.configs.has_section(str(section)) and self.parent.configs.has_option(str(section),str(option)): - value = str(self.parent.configs.get(str(section), str(option))) + if self.parent.configs_cover.has_section(str(section)) and self.parent.configs_cover.has_option(str(section),str(option)): + value = str(self.parent.configs_cover.get(str(section), str(option))) + logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+" GetConfigValue section:%s option:%s value:%s ...",section,option,value) + return True,value + if self.parent.configs_uncover.has_section(str(section)) and self.parent.configs_uncover.has_option(str(section),str(option)): + value = str(self.parent.configs_uncover.get(str(section), str(option))) logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+" GetConfigValue section:%s option:%s value:%s ...",section,option,value) return True,value elif self.parent.sqlite3_server.ucconfigs.has_section(str(section)) and self.parent.sqlite3_server.ucconfigs.has_option(str(section),str(option)): @@ -772,11 +777,6 @@ class UpdateManagerDbusController(dbus.service.Object): def UpdateDetectStatusChanged(self,progress,status): logging.info(COLORLOG_PREFIX+"Emitting"+COLORLOG_SUFFIX+" UpdateDetectStatusChanged progress = %d , status = %s",progress,status) - #替代UpdateDetectFinished 分发更新完成信号,为了解决发送空列表时 控制面板出段错误 - def DistUpdateDetectFinished(self, success, upgrade_group,error_string='',error_desc=''): - if success == False and upgrade_group == []: - upgrade_group = [''] - self.UpdateDetectFinished(success,upgrade_group,error_string,error_desc) #更新完成的信号 @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='basss') def UpdateDetectFinished(self, success, upgrade_group,error_string='',error_desc=''): @@ -894,7 +894,13 @@ class UpdateManagerDbusController(dbus.service.Object): @dbus.service.signal(UPDATER_DBUS_INTERFACE) def ChangeUpgradePolicy(self): logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" ChangeUpgradePolicy") - + + #下载安装前的状态检查信号 + @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bs') + def InstallDetectStatus(self, success,error_code=''): + logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " InstallDetectStatus success = %r , error_code = %s",\ + success,error_code) + WRITABLE_PROPERTIES = () # pylint: disable-msg=C0103,C0322 @@ -1003,9 +1009,11 @@ class UpdateManagerDbusController(dbus.service.Object): """Helper to set a property on the properties D-Bus interface.""" if iface == UPDATER_DBUS_INTERFACE: if name == "ShutdownInstall": - self.parent.configs.setValue("InstallMode","shutdown_install",str(bool(value))) + self.parent.configs_uncover.setValue("InstallMode","shutdown_install",str(bool(value))) elif name == "P2pBootstrap": self.parent.apt_p2p_config.set_bootstrap(str(value)) + elif name == "UploadUpgradeLog": + self.parent.configs_uncover.setValue("SystemStatus","upload_upgrade_log",str(bool(value))) else: raise dbus.exceptions.DBusException("Unknown or read only " "property: %s" % name) @@ -1018,9 +1026,12 @@ class UpdateManagerDbusController(dbus.service.Object): if iface == UPDATER_DBUS_INTERFACE: return { "ShutdownInstall": dbus.Boolean( - self.parent.configs.getWithDefault("InstallMode", "shutdown_install", False)), + self.parent.configs_uncover.getWithDefault("InstallMode", "shutdown_install", False)), - "P2pBootstrap": dbus.String(self.parent.apt_p2p_config.get_bootstrap()) + "P2pBootstrap": dbus.String(self.parent.apt_p2p_config.get_bootstrap()), + + "UploadUpgradeLog": dbus.Boolean( + self.parent.configs_uncover.getWithDefault("SystemStatus", "upload_upgrade_log", False)) } else: return {} \ No newline at end of file diff --git a/backend/SystemUpdater/backend/InstallBackendAptdaemon.py b/backend/SystemUpdater/backend/InstallBackendAptdaemon.py index a9ebb8e..3b8a713 100644 --- a/backend/SystemUpdater/backend/InstallBackendAptdaemon.py +++ b/backend/SystemUpdater/backend/InstallBackendAptdaemon.py @@ -21,7 +21,6 @@ import dbus,time from gi.repository import GLib import os from importlib import reload -from SystemUpdater.Core.utils import unLockedEnableShutdown,LockedPreventShutdown # 超时检测 秒单位 UPDATER_IDLE_CHECK_INTERVAL = 5 @@ -30,7 +29,6 @@ INSTALL_IDLE_TIMEOUT = 20 * 60 #更新超时检查 5分钟 UPDATE_IDLE_TIMEOUT = 5 * 60 - class InstallBackendAptdaemon(InstallBackend): """Makes use of aptdaemon to refresh the cache and to install updates.""" @@ -99,14 +97,13 @@ class InstallBackendAptdaemon(InstallBackend): if (time.time() - timestamp > INSTALL_IDLE_TIMEOUT and self.on_install_stage == True): logging.error("Quitting due to inactivity(%s)",self.aptd_base.details) - if self.action == self.ACTION_INSTALL_SHUTDOWN: #关机安装模式 解除禁止关机锁 - self.window_maininhibit_lock.close() + self.window_main.inhibit_lock.close() logging.info("Installtion timeout to exit Due to inactivity and Releasing the shutdown lock...") else: #超时只单独进行解锁关机 - unLockedEnableShutdown() + self.window_main.inhibit_shutdown.unlock() # self._action_done(self.ACTION_INSTALL, # is_cancelled=False, success=False, # #FIXME: 安装超时退出 @@ -298,8 +295,7 @@ class InstallBackendAptdaemon(InstallBackend): return self.aptd_base.progress = progress - self._dist_status_changed(action,self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs,\ - self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details) + self._dist_status_changed(action,self.now_upgrade.upgrade_content,self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details) #同步状态回调 @@ -312,7 +308,7 @@ class InstallBackendAptdaemon(InstallBackend): if self.aptd_base.status == None: return - self._dist_status_changed(action,self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs,\ + self._dist_status_changed(action,self.now_upgrade.upgrade_content,\ self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details) #分发进度状态和细节信息 @@ -329,10 +325,7 @@ class InstallBackendAptdaemon(InstallBackend): if progress > 51 and progress < 90 and self.on_install_stage == False: logging.info("The process is now in the installtion phase") self.on_install_stage = True - LockedPreventShutdown() - - #进度安装阶段标志位,使用鉴别是否出现安装过程中强制关闭 之后进行修复使用得 - self.window_main.configs.setValue("SystemStatus","abnormal_reboot",str(True),True) + self._start_install_lock() #只处理从下载切换到安装时出现的网络问题 #当网络波动时下载某些软件包失败时属于异常状态进行重试时 不发送后续进度 等待重试正常是 进行下载安装 diff --git a/backend/SystemUpdater/backend/__init__.py b/backend/SystemUpdater/backend/__init__.py index 027ec2a..9cba923 100644 --- a/backend/SystemUpdater/backend/__init__.py +++ b/backend/SystemUpdater/backend/__init__.py @@ -3,25 +3,19 @@ """Integration of package managers into SystemUpdater""" -import logging import os -from gettext import gettext as _ - import apt import apt_pkg import json -from SystemUpdater.Core.utils import ( - unLockedEnableShutdown, - get_broken_details -) -from SystemUpdater.Core.DataAcquisition import get_east_8_time -from apt import Cache +import logging import subprocess -from SystemUpdater.Core.UpdateList import LocalUpgradeDataList -from SystemUpdater.Core.errors import * import threading +from apt import Cache +from gettext import gettext as _ from SystemUpdater.Core.errors import * from SystemUpdater.Core.enums import * +from SystemUpdater.Core.DataAcquisition import get_east_8_time +from SystemUpdater.Core.UpdateList import LocalUpgradeDataList from SystemUpdater.Core.DistUpgradeCache import NotEnoughFreeSpaceError class NowUpgradeMeta: @@ -43,7 +37,7 @@ class NowUpgradeMeta: self.single_pkgs = single_pkgs self.version_upgrade = version_upgrade self.need_retry = need_retry - self.upgrade_content = upgrade_groups + single_pkgs + self.upgrade_content = self.upgrade_groups + self.single_pkgs #获取当前升级的升级列表 def _make_groups_list(self,upgrade_data,_upgrade_mode,partial_upgrade_list): @@ -70,8 +64,12 @@ class NowUpgradeMeta: return groups_list,pkg_list def make_upgrade_content(self,content): - self.upgrade_groups,self.single_pkgs = self._make_groups_list(self.parent.upgrade_data,self.parent.action_mode,content) - self.upgrade_content = self.upgrade_groups + self.single_pkgs + if self.parent.action_mode != self.parent.MODE_INSTALL_SINGLE: + self.upgrade_groups,self.single_pkgs = self._make_groups_list(self.parent.upgrade_data,self.parent.action_mode,content) + self.upgrade_content = self.upgrade_groups + self.single_pkgs + else: + self.single_pkgs = content + self.upgrade_content = self.upgrade_groups + self.single_pkgs class AptdBaseInformation: @@ -147,9 +145,8 @@ class InstallBackend(): try: #安装升级包 首先必须调用ACTION_CHECK_RESOLVER 计算依赖解决方便 标记cache 进行升级 if self.action == self.ACTION_INSTALL or self.action == self.ACTION_DOWNLOADONLY: - if self.action_mode != self.MODE_INSTALL_SINGLE: - #拿到升级列表 - self.now_upgrade.make_upgrade_content(partial_upgrade_list) + #拿到升级列表 + self.now_upgrade.make_upgrade_content(partial_upgrade_list) pkgs_install,pkgs_upgrade,pkgs_remove = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode) logging.info("INSTALL install:%d , upgrade:%d remove:%d",len(pkgs_install),len(pkgs_upgrade),len(pkgs_remove)) @@ -163,8 +160,8 @@ class InstallBackend(): if len(pkgs_install) == 0 and len(pkgs_upgrade) == 0 and len(pkgs_remove) == 0: raise UpdateBaseError(ERROR_NOT_UPGRADE_PACKAGES) - if self.action_mode == self.MODE_INSTALL_SINGLE: - logging.warning("MODE_INSTALL_SINGLE install:%s , upgrade:%s remove:%s",str(pkgs_install),str(pkgs_upgrade),str(pkgs_remove)) + # if self.action_mode == self.MODE_INSTALL_SINGLE: + # logging.warning("MODE_INSTALL_SINGLE install:%s , upgrade:%s remove:%s",str(pkgs_install),str(pkgs_upgrade),str(pkgs_remove)) self.window_main.update_essential.check(pkgs_remove) @@ -184,8 +181,7 @@ class InstallBackend(): self.now_upgrade,pkgs_install,pkgs_upgrade,pkgs_remove = self._config_to_upgrade() logging.info("ACTION_INSTALL_SHUTDOWN install:%d , upgrade:%d remove:%d",len(pkgs_install),len(pkgs_upgrade),len(pkgs_remove)) - #进度安装阶段标志位,使用鉴别是否出现安装过程中强制关闭 之后进行修复使用得 - self.window_main.configs.setValue("SystemStatus","abnormal_reboot",str(True),True) + # self._start_install_lock() self.commit(self.action,pkgs_install, pkgs_upgrade, pkgs_remove) #计算依赖解决方案 @@ -257,27 +253,8 @@ class InstallBackend(): self.fix_incomplete() #卸载包 elif self.action == self.ACTION_REMOVE_PACKAGES: - # remove_pkgs = [] - # for pkg in partial_upgrade_list: - # if pkg in self.cache: - # pkg_cache = self.cache[pkg] - # pkg_cache.mark_delete(True, True) - # else: - # #没有在cache中就认为不需要升级 - # logging.error("Check: (%s) The reomve package is not in Cache...",pkg) - - # for pkg_obj in self.cache.get_changes(): - # if pkg_obj.marked_delete: - # remove_pkgs.append(pkg_obj.name) - - # success,header,desc = self.check_essential_pkgs(remove_pkgs) - # if success == False: - # self._action_done(self.action,False,False,header,desc) - # return - # else: + self._start_install_lock() self.purge_packages(partial_upgrade_list) - - #清空所有下载的文件 elif self.action == self.ACTION_CLEAN: self.clean() #更新cache @@ -286,17 +263,17 @@ class InstallBackend(): self.window_main.check_conifg_aptdeamon() self.update() except UpdateBaseError as excep: - self._action_done(self.action,True,False,excep.header,excep.desc) + self._action_done(self.action,True,False,excep.header,excep.desc,excep.code) except UpdateProgressExit as excep: pass except Exception as e: - logging.error(e) - + logging.error(e) def start_alone(self,partial_upgrade_list = [],_is_install = False): # 安装本地deb包的接口 if self.action == self.ACTION_INSTALL_DEB: try: + self._start_install_lock() self.install_deb(install_path = partial_upgrade_list, install_force = _is_install) except Exception as e: logging.error(str(e)) @@ -472,7 +449,7 @@ class InstallBackend(): resolver.protect(pkg_cache) #出现破损的原因有 升级一个包需要安装其他的包或者需要删除其他的软件包 if cache._depcache.broken_count != last_broken_count and \ - self.window_main.configs.getWithDefault("ConfigPkgStatus", "check_resover_remove", False) == True: + self.window_main.configs_cover.getWithDefault("ConfigPkgStatus", "check_resover_remove", False) == True: last_broken_count = cache._depcache.broken_count tmp_pkgs,tmp_desc = self._emulate_calcul_delete(pkg,fresh_cache) delete_pkgs.extend(tmp_pkgs) @@ -482,18 +459,14 @@ class InstallBackend(): return delete_pkgs,delete_desc except Exception as e: logging.info(str(e)) - # msg = get_broken_details(cache,False) pkg_string = '' for pkg in pkgs_install + pkgs_upgrade: pkg_string = pkg_string + ' ' + str(pkg) logging.info('Resolver calculation Packages List: '+pkg_string+'\n') - # logging.error('\n' + msg) - terminal_msg = self.emulate_calcul_broken(pkgs_install + pkgs_upgrade) + terminal_msg = self.window_main.simulate_mode.dependencies_broken(pkgs_install + pkgs_upgrade) logging.error(terminal_msg) raise UpdateBaseError(ERROR_RESOLVER_FAILED, desc= terminal_msg) - # threading_emulate = threading.Thread(target=emulate_calcul_broken,args=(pkgs_install + pkgs_upgrade,)) - # threading_emulate.start() def _emulate_calcul_delete(self,pkg,cache): try: @@ -521,53 +494,53 @@ class InstallBackend(): logging.error("Package("+pkg+") "+ str(e)) return [],[] - #调用aptdeamon结束之后处理的地方 不管是出错还是正常都在此处理 - def _action_done(self, action, is_cancelled,success, error_string,error_desc): - #后端的状态 到空闲状态 - self.window_main.now_working = self.ACTION_DEFUALT_STATUS + def _send_error_code(self,error_code): + if error_code == ERROR_NOT_DISK_SPACE: + self.window_main.dbusController.InstallDetectStatus(False,error_code) + def _self_upgrade_finished(self,success,error_string='',error_desc=''): + if success: + if self.window_main.configs_cover.getWithDefault("SystemStatus", "priority_upgrade_restart", False) == True: + error_string = get_error_string_from_enum(PRIORITY_UPGRADE_SUCCCESSED) + if self.window_main.APTD_PKG_NAME in self.now_upgrade.upgrade_content: + self.window_main.dbusController.UpdateDetectFinished(False,[self.window_main.BACKEND_PKG_NAME],error_string,'') + self.window_main.dbusController.make_aptdeamon_restart() + + #当单包升级的时候 升级本身时,让程序退出,再重新启动 + if self.window_main.FRONTEND_PKG_NAME in self.now_upgrade.upgrade_content: + self.window_main.dbusController.UpdateDetectFinished(False,[self.window_main.BACKEND_PKG_NAME],error_string,'') + + #当单包升级的时候 升级本身时,让程序退出,再重新启动 + if self.window_main.BACKEND_PKG_NAME in self.now_upgrade.upgrade_content: + self.window_main.dbusController.UpdateDetectFinished(False,[self.window_main.BACKEND_PKG_NAME],error_string,'') + #升级本身完成后 退出 有systemd 来进行重启服务 + self.window_main.dbusController.Quit(None) + + #当单包升级的时候 升级本身时,让程序退出,再重新启动 + if self.window_main.GROUPS_PKG_NAME in self.now_upgrade.upgrade_content: + #只有安装配置文件包 才会走到此处 + self.window_main.update_essential.update() + self.window_main.start_available() + else: + #只有安装配置文件包 才会走到此处 + self.window_main.update_essential.update() + self.window_main.start_available() + else: + self.window_main.dbusController.UpdateDetectFinished(False,[''],get_error_string_from_enum(ERROR_UPDATE_DEFAULT_FAILED),\ + error_string +' '+error_desc) + + #调用aptdeamon结束之后处理的地方 不管是出错还是正常都在此处理 + def _action_done(self, action, is_cancelled,success, error_string,error_desc,error_code=''): + #后端的状态 到空闲状态 + self.window_main.now_working = self.ACTION_DEFUALT_STATUS + #升级完成后走的分支 if action == self.ACTION_INSTALL: - #记录这个过程中是否关机 - self.window_main.configs.setValue("SystemStatus","abnormal_reboot",str(False),True) - #解锁 禁止关机 - unLockedEnableShutdown() - - #单包安装模式 单独处理 目前 更新配置包和升级本身使用 + self._release_install_lock() + self._send_error_code(error_code) + if self.action_mode == self.MODE_INSTALL_SINGLE: - if success: - if self.window_main.APTD_PKG_NAME in self.cache and self.cache[self.window_main.APTD_PKG_NAME] in self.cache.get_changes(): - error_string = _("Update Manager upgrade is complete, please restart the control panel before performing the system update") - self.window_main.dbusController.DistUpdateDetectFinished(False,[self.window_main.BACKEND_PKG_NAME],error_string,error_desc) - self.window_main.dbusController.make_aptdeamon_restart() - - #当单包升级的时候 升级本身时,让程序退出,再重新启动 - if self.window_main.FRONTEND_PKG_NAME in self.cache and self.cache[self.window_main.FRONTEND_PKG_NAME] in self.cache.get_changes(): - error_string = _("Update Manager upgrade is complete, please restart the control panel before performing the system update") - self.window_main.dbusController.DistUpdateDetectFinished(False,[self.window_main.BACKEND_PKG_NAME],error_string,error_desc) - - #当单包升级的时候 升级本身时,让程序退出,再重新启动 - if self.window_main.BACKEND_PKG_NAME in self.cache and self.cache[self.window_main.BACKEND_PKG_NAME] in self.cache.get_changes(): - error_string = _("Update Manager upgrade is complete, please restart the control panel before performing the system update") - self.window_main.dbusController.DistUpdateDetectFinished(False,[self.window_main.BACKEND_PKG_NAME],error_string,error_desc) - #升级本身完成后 退出 有systemd 来进行重启服务 - self.window_main.dbusController.Quit(None) - - #当单包升级的时候 升级本身时,让程序退出,再重新启动 - if self.window_main.GROUPS_PKG_NAME in self.cache and self.cache[self.window_main.GROUPS_PKG_NAME] in self.cache.get_changes(): - #只有安装配置文件包 才会走到此处 - self.window_main.update_essential.update() - self.window_main.start_available() - - return - else: - #当更新过程中安装配置包时 失败时发送错误信号 - # 防止错误结果太长导致出现控制面板显示太多 目前最多20字符 - if len(error_string + error_desc) > 20: - self.window_main.dbusController.DistUpdateDetectFinished(success,[],error_string,error_desc) - else: - self.window_main.dbusController.DistUpdateDetectFinished(success,[],error_string+','+error_desc,error_desc) - return + self._self_upgrade_finished(success,error_string,error_desc) else: if self.now_upgrade.version_upgrade == True and self.now_upgrade.need_retry == True and success == False: #增加重试次数的限制 @@ -609,7 +582,7 @@ class InstallBackend(): self.window_main.refresh_cache() elif action == self.ACTION_INSTALL_SHUTDOWN: - self.window_main.configs.setValue("SystemStatus","abnormal_reboot",str(False)) + # self._release_install_lock() #插入数据库 self.window_main.sqlite3_server.insert_info(self.ACTION_INSTALL,self.now_upgrade.single_pkgs,\ self.now_upgrade.upgrade_groups,[],success,error_string,error_desc) @@ -629,17 +602,7 @@ class InstallBackend(): self.window_main.dbusController.Quit(None) elif action == self.ACTION_CHECK_RESOLVER: - zh_desc = '下列软件包有未满足的依赖关系:' - en_desc = 'The following packages have unmet dependencies:' - if success == False: - if len(error_desc) > 500: - error_desc = '' - if zh_desc in error_desc: - error_desc = '\n' + zh_desc + error_desc.split(zh_desc)[1] - elif en_desc in error_desc: - error_desc = '\n' + en_desc + error_desc.split(en_desc)[1] - self.window_main.sqlite3_server.insert_info(self.action_mode,self.now_upgrade.single_pkgs,\ self.now_upgrade.upgrade_groups,[],success,error_string,error_desc) @@ -673,27 +636,29 @@ class InstallBackend(): self.window_main.dbusController.UpdateDownloadFinished(success,self.now_upgrade.upgrade_content,error_string,error_desc) - elif action == self.ACTION_UPDATE: - if success == False and ERROR_UPDATE_KEY_SIGNATURES in self.aptd_base.error_details: - error_desc = _("Check your source public key signature") - #网络认证错误 - elif success == False and 'does the network require authentication?' in self.aptd_base.error_details: - error_desc = _("Check if your network requires authentication?") - - if success and self.action_mode == self.MODE_UPDATE_ALL: - #开始生成列表 - self.window_main.start_available() - else: - self.window_main.dbusController.DistUpdateDetectFinished(success,[],error_string+','+error_desc,error_desc) - - if self.action_mode == self.MODE_UPDATE_ALL: - #记录本次更新时间插入数据库 - self.window_main.sqlite3_server.insert_into_display("check_time",get_east_8_time()) - - if success == False and self.action_mode == self.MODE_UPDATE_ALL: + elif action == self.ACTION_UPDATE and self.action_mode == self.MODE_UPDATE_ALL: + if success == False: threading_emulate = threading.Thread(target=self.emulate_update) threading_emulate.start() + if ERROR_UPDATE_KEY_SIGNATURES in self.aptd_base.error_details: + error_desc = get_error_description_from_enum(ERROR_UPDATE_KEY_SIGNATURES) + elif ERROR_UPDATE_NET_AUTHENTICATION in self.aptd_base.error_details: + error_desc = get_error_description_from_enum(ERROR_UPDATE_NET_AUTHENTICATION) + elif ERROR_UPDATE_NOTREAD_SOURCES in self.aptd_base.error_details: + error_desc = get_error_description_from_enum(ERROR_UPDATE_NOTREAD_SOURCES) + + if success: + #开始生成列表 + self.window_main.start_available() + else: + self.window_main.dbusController.UpdateDetectFinished(success,[''],\ + get_error_string_from_enum(ERROR_UPDATE_DEFAULT_FAILED),error_string+' '+error_desc) + + self.window_main.sqlite3_server.insert_into_display("check_time",get_east_8_time()) + + elif action == self.ACTION_UPDATE and self.action_mode == self.MODE_UPDATE_CACHE: + self.window_main.dbusController.UpdateDetectFinished(success,[''],error_string,error_desc) elif action == self.ACTION_FIX_BROKEN: self.window_main.dbusController.FixBrokenStatusChanged(True,success,100,'',error_string,error_desc) logging.warning("fix broken packages is complete...") @@ -702,7 +667,8 @@ class InstallBackend(): logging.info("Fix broken packages is complete to success...") self.window_main.start_available() else: - self.window_main.dbusController.DistUpdateDetectFinished(success,[],error_string,error_desc) + self.window_main.dbusController.UpdateDetectFinished(success,[''],\ + get_error_string_from_enum(ERROR_UPDATE_DEFAULT_FAILED),error_string+' '+error_desc) logging.error("fix broken packages is complete to failed...") elif action == self.ACTION_FIX_INCOMPLETE: @@ -712,15 +678,18 @@ class InstallBackend(): logging.warning("fix incomplete install failed.") elif action == self.ACTION_REMOVE_PACKAGES: + self._release_install_lock() self.window_main.dbusController.PurgePackagesFinished(success,error_string,error_desc) elif action == self.ACTION_INSTALL_DEB: + self._release_install_lock() #FIXME: '\r\n: \r\n\r\n'就认为是验证失败 if success == False and '\r\n: \r\n\r\n' in self.aptd_base.error_details: error_string = _("Package validation failed and installation was rejected.") error_desc = '' self.window_main.dbusController.InstalldebFinished(success,error_string,error_desc) elif action == self.ACTION_BACKGROUND_UPGRADE: + self._release_install_lock() UpdateMsg = {} if success: status = 'Success' @@ -740,6 +709,14 @@ class InstallBackend(): self.window_main.dbusController.UpdateInstallFinished(success,self.now_upgrade.upgrade_content,error_string,error_desc) + def _start_install_lock(self): + self.window_main.configs_uncover.setValue("SystemStatus","abnormal_reboot",str(True)) + self.window_main.inhibit_shutdown.lock() + + def _release_install_lock(self): + self.window_main.configs_uncover.setValue("SystemStatus","abnormal_reboot",str(False)) + self.window_main.inhibit_shutdown.unlock() + def _message_to_plymouth(self,message): subprocess.call(["/bin/plymouth", "message", "--text", message]) diff --git a/backend/data/system-updater.conf b/backend/data/system-updater-coverable.conf old mode 100644 new mode 100755 similarity index 59% rename from backend/data/system-updater.conf rename to backend/data/system-updater-coverable.conf index 65e354a..9f66427 --- a/backend/data/system-updater.conf +++ b/backend/data/system-updater-coverable.conf @@ -1,14 +1,11 @@ [SystemStatus] -abnormal_reboot = False close_source_filter = False +priority_upgrade_restart = True [ConfigPkgStatus] check_resover_remove = False check_frontend_pkg = True -[InstallMode] -shutdown_install = False -manual_install = False -auto_install = False +[AutoUpgradeConfig] upgradeInterval = 7 downloadRandom = 180 diff --git a/backend/data/system-updater-defaults.conf b/backend/data/system-updater-defaults.conf index ebfed79..f454660 100644 --- a/backend/data/system-updater-defaults.conf +++ b/backend/data/system-updater-defaults.conf @@ -1,13 +1,6 @@ -[AutoUpgrade] -upgradelist = - [SystemStatus] abnormal_reboot = False -close_source_filter = False - -[ConfigPkgStatus] -check_resover_remove = False -check_frontend_pkg = True +upload_upgrade_log = False [InstallMode] shutdown_install = False diff --git a/backend/data/system-updater-uncoverable.conf b/backend/data/system-updater-uncoverable.conf deleted file mode 100644 index 3305344..0000000 --- a/backend/data/system-updater-uncoverable.conf +++ /dev/null @@ -1,6 +0,0 @@ -[UpdaterStatus] -first_run = yes - -[SYSTEM] -version = -kylin_release_id = \ No newline at end of file diff --git a/backend/interface.md b/backend/interface.md index abf739b..c7536ee 100755 --- a/backend/interface.md +++ b/backend/interface.md @@ -520,6 +520,27 @@ +#### InstallDetectStatus + +- `介绍:`下载安装前的状态检查 + +- `出参`: `b:`检查出错时为`False`,没有错误`success`,`s:`产生错误的码 + +- 错误码示例: + + ```python + ERROR_NOT_DISK_SPACE = "error-not-disk-space" + ``` + +- `示例:` + + ```sh + #表示出现磁盘已满的错误z + InstallDetectStatus success = False , error_code = "error-not-disk-space" + ``` + + + diff --git a/backend/kylin-system-updater b/backend/kylin-system-updater index 206a5b2..a89c0e7 100755 --- a/backend/kylin-system-updater +++ b/backend/kylin-system-updater @@ -85,18 +85,15 @@ if __name__ == "__main__": logging.info('kylin-system-updater(lang:%s) starting ...',os.environ["LANGUAGE"]) - try: - app = UpdateManager(options) + app = UpdateManager(options) - #当出现安装过程中异常的重启时 开机直接进行修复操作 - if app.configs.getWithDefault("ConfigPkgStatus", "check_frontend_pkg", False) == True: - app.configs.setValue("ConfigPkgStatus","check_frontend_pkg",str(False),True) - app.check_frontend_pkg() + #当出现安装过程中异常的重启时 开机直接进行修复操作 + # if app.configs_cover.getWithDefault("ConfigPkgStatus", "check_frontend_pkg", False) == True: + # app.configs_cover.setValue("ConfigPkgStatus","check_frontend_pkg",str(False),True) + # app.check_frontend_pkg() - #当出现安装过程中异常的重启时 开机直接进行修复操作 - if app.configs.getWithDefault("SystemStatus", "abnormal_reboot", False) == True: - app.start_update() + #当出现安装过程中异常的重启时 开机直接进行修复操作 + if app.configs_uncover.getWithDefault("SystemStatus", "abnormal_reboot", False) == True: + app.start_update() - app.run() - except Exception as e: - logging.error(e) \ No newline at end of file + app.run() \ No newline at end of file diff --git a/backend/po/zh_CN.po b/backend/po/zh_CN.po index 6b587ca..162c127 100644 --- a/backend/po/zh_CN.po +++ b/backend/po/zh_CN.po @@ -616,8 +616,8 @@ msgid "Checking package manager" msgstr "正在检查软件包管理器" #: ../DistUpgrade/DistUpgradeController.py:1593 -msgid "Unable to get group configuration package, please contact administrator to solve" -msgstr "无法获取组配置软件包,请联系管理员解决" +msgid "Unable to get group configuration package, please contact administrator to solve." +msgstr "无法获取组配置软件包,请联系管理员解决。" #: ../DistUpgrade/DistUpgradeController.py:1594 msgid "" @@ -2599,7 +2599,7 @@ msgid "Installation failed, about to shut down" msgstr "安装失败,即将关机" msgid "groups JSON ConfigPkgs install failed" -msgstr "无法安装分组配置文件,请稍后再试" +msgstr "无法安装分组配置文件" msgid "Installtion timeout to exit Due to inactivity" msgstr "安装超时退出由于" @@ -2622,9 +2622,15 @@ msgstr "依赖关系不满足" msgid "Disk space is insufficient, please clean the disk and then upgrade" msgstr "磁盘空间不足,请清理磁盘后进行升级更新" +msgid "Check for update exceptions,please check your network connection and retry." +msgstr "检查更新异常,请检查您的网络连接后再试。" + msgid "Please check your network connection and retry." msgstr "请检查您的网络连接后再试。" +msgid "Please check your source list and retry." +msgstr "请检查您的源列表后再试。" + msgid "Checking network connection" msgstr "检查网络连接中" diff --git a/debian/changelog b/debian/changelog index 15f1901..7e770cd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,16 @@ +kylin-system-updater (2.0.5.1) v101; urgency=medium + + * BUG: # 121890 【更新升级】部分应用更新完成后,在“查看历史更新”中查不到数据 + # 123985 【在线更新】系统存在可选更新且在设置中开启了自动下载和安装更新,系统到达定时下载的时间未进行自动下载 + # 110370 【更新升级】 【自动更新】出现一次,自动更新安装服务,将本地安装包地址检测成源地址导致安装报错 + * 需求号: # 12722 【更新升级】系统更新全流程监控 + # 12720 【更新升级】升级环境检测 + # 12721 【更新升级】系统版本号体系 + * 其他改动说明: 无 + * 其他改动影响域:系统更新 + + -- luoxueyi Mon, 13 Jun 2022 16:25:38 +0800 + kylin-system-updater (2.0.4.3) v101; urgency=medium * BUG: # 118021 【在线更新】中文环境下,安装和卸载应用时弹出授权界面,提示内容未汉化 diff --git a/debian/kylin-system-updater.install b/debian/kylin-system-updater.install index 7cd621e..949ac54 100644 --- a/debian/kylin-system-updater.install +++ b/debian/kylin-system-updater.install @@ -12,11 +12,11 @@ backend/SystemUpdater/*.py /usr/share/kylin-system-updater/SystemUpdater/ backend/SystemUpdater/backend/*.py /usr/share/kylin-system-updater/SystemUpdater/backend/ backend/SystemUpdater/Core/*.py /usr/share/kylin-system-updater/SystemUpdater/Core/ backend/build/mo/* /usr/share/locale/ -backend/data/system-updater.conf /var/lib/kylin-system-updater/ +backend/data/system-updater-defaults.conf /var/lib/kylin-system-updater/ +backend/data/system-updater-coverable.conf /var/lib/kylin-system-updater/ backend/data/unattended-upgrades-policy.conf /var/lib/unattended-upgrades/ backend/data/unattended-upgrades-timestamp /var/lib/unattended-upgrades/ backend/data/cn.kylinos.KylinSystemUpdater.policy /usr/share/polkit-1/actions/ -backend/data/system-updater-uncoverable.conf /usr/share/kylin-system-updater/ #uu unattended-upgrades/*.service /lib/systemd/system/ diff --git a/debian/postinst b/debian/postinst index d2476cd..b3049a5 100644 --- a/debian/postinst +++ b/debian/postinst @@ -19,7 +19,3 @@ if [ -f /usr/share/kylin-system-updater/SystemUpdater/Core/DataMigration.py ];th /usr/share/kylin-system-updater/SystemUpdater/Core/DataMigration.py -u appname_cn= /usr/share/kylin-system-updater/SystemUpdater/Core/DataMigration.py -t=tid_search fi - -if [ ! -f /var/lib/kylin-system-updater/system-updater-uncoverable.conf ];then - cp /usr/share/kylin-system-updater/system-updater-uncoverable.conf /var/lib/kylin-system-updater/ -fi