Merge branch 'backend_uu' of gitlab2.kylin.com:kylin-desktop/update-manager-group/kylin-system-updater into backend_uu

This commit is contained in:
wangsong 2022-06-01 09:23:57 +08:00
commit 26e55a9518
16 changed files with 580 additions and 305 deletions

View File

@ -2,25 +2,32 @@
# supervisory control and data acquisition
#!/usr/bin/python3
from email import message
import os
import json
import dbus
import uuid
import time
import socket
import base64
import shutil
import hashlib
import logging
import tarfile
import requests
import datetime
import configparser
from datetime import datetime
import threading
from email import message
from binascii import a2b_hex
from datetime import datetime
from Crypto.PublicKey import RSA
from urllib import parse, request
from PyQt5.QtCore import QSettings
from SystemUpdater.Core import enums
from Crypto.Cipher import PKCS1_OAEP
from json.decoder import JSONDecodeError
from dbus.exceptions import DBusException
from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
from SystemUpdater.Core import enums
LOCALTIDDIR = "/var/lib/kylin-system-updater/"
LOCALTIDFILE = "tidfile.conf"
@ -68,9 +75,9 @@ class UpdateMsgCollector():
action_map = {
ACTION_CHECK_RESOLVER:enums.MONIT_DEPRESOLUT,
ACTION_INSTALL:enums.MONIT_INSTALL,
10:enums.MONIT_FINISH,
"finish-update":enums.MONIT_FINISH,
"finish-install":enums.MONIT_FINISH
}
messageType_map = {
# InstallBackend.ACTION_CHECK_RESOLVER:"UpdateDetect",
@ -78,6 +85,7 @@ class UpdateMsgCollector():
# InstallBackend.ACTION_CHECK_RESOLVER:"Downloading",
ACTION_INSTALL:"Installing",
# InstallBackend.ACTION_CHECK_RESOLVER:"UpgradeFinish",
10:"Background-upgrade",
"finish-update":"UpdateInfos",
"finish-install":"InstallInfos"
}
@ -90,8 +98,12 @@ class UpdateMsgCollector():
self.UploadMessage = {}
self.PackageInfo = {}
self.UpdateInfos = {}
self.background_version = {}
self.background_upgradable = []
self.background_list = []
self.upgrade_list = []
self.waitSendList = []
self.cache = None
self.updateManager = manager
# 转换 & 加密
@ -150,7 +162,7 @@ class UpdateMsgCollector():
# 生成UploadMessage与PackageInfo
try:
self.GenPackageInfo(messageType, "Upgrade-Process-Monitor")
self.GenPackageInfo(messageType, "kylin-system-updater")
self.GenUploadMessage(dict_message, local_uuid = uuid)
except Exception as e:
logging.error(str(e))
@ -172,7 +184,7 @@ class UpdateMsgCollector():
self.upgrade_list = upgrade_list
self.upgrade_mode = mode
self.uuid = str(uuid.uuid1())
self.UpdateInfos.update({"upgradeMode":self.mode_map.get(self.upgrade_mode, "")})
self.UpdateInfos.update({"upgradeMode":self.mode_map.get(self.upgrade_mode, "default-mode")})
except DBusException as e:
logging.error(e)
@ -187,24 +199,24 @@ class UpdateMsgCollector():
json_file = json.dumps(tmp_dict.copy())
self.UpdateMsg(self.messageType_map.get(action, ""), json_file, self.uuid)
else:
for ul in self.upgrade_list:
self.UpdateInfos.update({"appname":str(ul)})
tmp_dict.update(self.UpdateInfos)
json_file = json.dumps(tmp_dict.copy())
self.UpdateMsg(self.messageType_map.get(action, ""), json_file, self.uuid)
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:
self.background_version.update({pkg.name:pkg.installed.source_version})
else:
self.background_version.update({pkg.name:"Unknown"})
self.background_list.append(pkg.name)
def Msg_Clean(self):
# self.uuid = ''
# self.status = ''
# self.upgrade_mode = ''
# self.upgrade_action = ''
self.UploadMessage = {}
self.PackageInfo = {}
self.UpdateInfos = {}
# self.upgrade_list = []
class FormatConvert():
def __init__(self, DataCollector):
@ -437,7 +449,106 @@ TQo1NXorMFVqdS8zSFJhNFY3b3p2TGRPRE5HUURaeWNJU0l3VHBLbFR3RjBxazdCNjVhTUlJenQ1\
dnhOK1lxYU1GClppZFRLNzcxNjdqNEExZ3F3MG45bjlybWVXUGRWZ3dudnRtVXp4Q1krNk05SXpK\
TDI3eWpRUTV1WGQ3RVdMT3IKbndJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="
class PHPServer(threading.Thread):
LOG_PATH = "/var/log/kylin-system-updater"
KYLIN_SOFTWARE_PROPERTIES_LOG = "/var/log/kylin-software-properties.log"
PINGBACK_INTERNET_URL = "http://archive1.kylinos.cn:32294/kylin-update-manager-server/main.php?"
PINGBACK_INTERNET_FILE_URL = "http://archive1.kylinos.cn:32294/kylin-update-manager-server/get_file.php?"
PINGBACK_INTRANET_URL = "http://archive.kylinos-intranet.cn/kylin-update-manager-server/main.php?"
PINGBACK_INTRANET_FILE_URL = "http://archive.kylinos-intranet.cn/kylin-update-manager-server/get_file.php?"
def get_values(self, _appname="", _appversion="", _state='', _errorcode=''):
self.appname = _appname
self.appversion = _appversion
self.status = _state
self.errorcode = _errorcode
def run(self):
# 获取本机ip
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 80))
host_ip = s.getsockname()[0]
except:
host_ip = 'Ip failed to get'
# 获取系统版本
with open('/etc/lsb-release', 'r') as f:
for line in f.readlines():
if line.strip().startswith('DISTRIB_DESCRIPTION='):
versions = line.strip().split('=')
if "V10" in line and "SP1" in versions[1]:
version = "V10SP1"
else:
version = "V10Pro"
break
# 获取软件版本
output = os.popen('dpkg -l|grep kylin-system-updater').readlines()
if output:
soft_version = output[0].strip().split()[2]
# 获取时间
nowtime = time.strftime('%Y-%m-%d-%H:%M:%S', time.localtime(time.time()))
# 获取Mac
mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
host_mac = ":".join([mac[e:e + 2] for e in range(0, 11, 2)])
# 获取序列号
if os.path.exists("/etc/.kyinfo"):
settings = QSettings("/etc/.kyinfo", QSettings.IniFormat)
settings.beginGroup("servicekey")
key = str(settings.value("key")).strip()
settings.endGroup()
else:
key = "0"
try:
# 用于收集源管理器的更新日志
if self.status == "success":
nowtime = datetime.utcnow( ).strftime ( '%Y-%m-%d %H:%M:%S.%f' )[:-3]
log_dir = os.path.join(self.LOG_PATH, host_mac + "_" + nowtime)
log_file_gzip = log_dir + ".tar.gz"
os.makedirs(log_dir, exist_ok=True)
if os.path.exists(self.KYLIN_SOFTWARE_PROPERTIES_LOG):
with open(os.path.join(log_dir, "apt_list"), "w") as f:
for file in os.listdir("/var/lib/apt/lists"):
f.write(file + "\n")
shutil.copy(self.KYLIN_SOFTWARE_PROPERTIES_LOG, log_dir)
gZipFile(log_dir, log_file_gzip)
header = {'Content-Type': "multipart/form-data", "Accept-Encoding": "gzip"}
try:
with open(log_file_gzip, "rb") as f:
requests.post(self.PINGBACK_INTRANET_FILE_URL + "filename=" + os.path.basename(log_file_gzip),
data=f.read(), headers=header)
except:
with open(log_file_gzip, "rb") as f:
requests.post(self.PINGBACK_INTERNET_FILE_URL + "filename=" + os.path.basename(log_file_gzip),
data=f.read(), headers=header)
shutil.rmtree(log_dir)
os.remove(log_file_gzip)
else:
log_file_gzip = ""
kmg = parse.urlencode(
{'ip': host_ip, 'version': version, 'soft_version': soft_version, 'datetime': nowtime,
'host_mac': host_mac, 'appname': self.appname, 'appversion': self.appversion, 'serial_number': key,
'state': self.status, 'filename': log_file_gzip, 'errorcode': self.errorcode})
# 优先使用内网服务器,再使用外网
try:
url = self.PINGBACK_INTRANET_URL + kmg
req = request.urlopen(url=url, timeout=3)
logging.info("The Intranet log server is successfully accessed, pkgname:%s .",self.appname)
except:
url = self.PINGBACK_INTERNET_URL + kmg
req = request.urlopen(url=url, timeout=3)
logging.info("The external log server is successfully accessed, pkgname:%s .",self.appname)
except Exception as e:
logging.error("Failed to access the external log server: %s, pkgname:%s .", e, self.appname)
os.remove(log_file_gzip)
def PHPSeverSend(_appname="", _appversion="", _statue="", _errorcode=""):
send_thread = PHPServer()
send_thread.get_values(_appname=_appname, _appversion=_appversion, _state=_statue, _errorcode=_errorcode)
send_thread.start()
def gZipFile(src, dst):
with tarfile.open(dst, "w:gz") as tar:
tar.add(src, arcname=os.path.basename(src))
def get_east_8_time():
import time

View File

@ -9,6 +9,7 @@ import sqlite3
import logging
import datetime
from gettext import gettext as _
from SystemUpdater.Core.DataAcquisition import PHPSeverSend
from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
import apt_pkg
@ -209,6 +210,9 @@ class Sqlite3Server(object):
if "=" in str(pkgversion):
version = str(pkgversion).split('=')[-1]
self._refresh_system_version(version)
#FIXME: 临时方案 PHP
PHPSeverSend(_appname=pkgname, _appversion=pkgversion, _statue=status, _errorcode="10000100")
elif pkg_list:
# 单包更新 # 获取单包数据插入数据库
pkgname = pkg_list.pop(0)
@ -257,6 +261,8 @@ class Sqlite3Server(object):
self.window_main.collector.Upgrade_Process_Msg("finish-install", InstallInfos.copy())
# 软件商店获取中文名
appname_cn = self.get_cn_appname(str(pkgname))
#FIXME: 临时方案 PHP
PHPSeverSend(_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
@ -308,6 +314,8 @@ class Sqlite3Server(object):
self.init_sqlit()
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")
# insert group deb next
for i in pkg_group:
# FIXME: 获取组信息
@ -328,6 +336,8 @@ class Sqlite3Server(object):
InstallInfos.update({"status":status})
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")
try:
self.insert_into_updateinfo(str(i), pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn)
self.window_main.dbusController.UpdateSqlitSingle(str(i), timestr)
@ -350,12 +360,11 @@ class Sqlite3Server(object):
# 获取group信息
def GetGroupmsg(self, appname):
INPUT_CONFIG_PATH = '/usr/share/kylin-update-desktop-config/data/'
jsonfile = appname+".json"
files = os.listdir(INPUT_CONFIG_PATH) #获取文件夹中所有文件
files = os.listdir(self.window_main.config_path) #获取文件夹中所有文件
if jsonfile in files: # 存在
# 读取组JSON文件
with open(INPUT_CONFIG_PATH+jsonfile, "r") as f:
with open(self.window_main.config_path+jsonfile, "r") as f:
try :
data = json.load(f)
except json.JSONDecodeError as e:
@ -465,7 +474,7 @@ class Sqlite3Server(object):
def get_default_version(self):
update_version = ""
os_version = ""
INPUT_CONFIG_PATH = '/usr/share/kylin-update-desktop-config/data/kylin-update-desktop-system.json'
INPUT_CONFIG_PATH = self.window_main.config_path + 'kylin-update-desktop-system.json'
if os.path.isfile(INPUT_CONFIG_PATH): # 存在
# 读取JSON文件
with open(INPUT_CONFIG_PATH, "r") as f:
@ -486,7 +495,7 @@ class Sqlite3Server(object):
for line in lines:
if "KYLIN_RELEASE_ID" in line:
os_version = line.split('=')[1]
os_version = os_version.strip()
os_version = eval(os_version.strip())
if update_version == "" and os_version != "":
update_version = os_version
elif update_version != "" and os_version == "":
@ -505,10 +514,16 @@ class Sqlite3Server(object):
sql = "select display_name_cn from application where display_name='"+name+"'"
cursor.execute(sql)
connect.commit()
retval = cursor.fetchone()
if len(retval) != 0:
return str(retval[0])
else:
return ''
except Exception as e:
logging.error(_("Failed to initialize the database: %s"), str(e))
return False
return str(cursor.fetchone()[0])
return ''
def listtojsonstr(lists):
import json

View File

@ -30,7 +30,6 @@ import apt
import apt_pkg
ImportantListPath="/var/lib/kylin-software-properties/template/important.list"
DesktopSystemPath="/usr/share/kylin-update-desktop-config/data/"
SOURCESLIST = "/etc/apt/sources.list"
# no py3 lsb_release in debian :/
@ -107,7 +106,7 @@ class UpdateListFilterCache(apt.Cache):
exit(-1)
# 获取/usr/share/kylin-update-desktop-config/data/下所有json文件
for root,dirs,files in os.walk(DesktopSystemPath):
for root,dirs,files in os.walk(self.window_main.config_path):
pass
for i in files:
if ".json" in i:
@ -124,7 +123,7 @@ class UpdateListFilterCache(apt.Cache):
# 在分组中
# 获取每个对应json文件中的upgrade_list
if i in jsonfiles:
filepath = os.path.join(DesktopSystemPath, i)
filepath = os.path.join(self.window_main.config_path, i)
filepath = filepath+".json"
with open(filepath, 'r') as f:
pkgdict = f.read()

View File

@ -35,7 +35,6 @@ class LocalUpgradeDataList:
class UpdateList():
OUTPUT_CONFIG_PATH = '/var/lib/kylin-system-updater/json/'
INPUT_CONFIG_PATH = '/usr/share/kylin-update-desktop-config/data/'
IMPORTANT_LIST_PATH = '/var/lib/kylin-software-properties/template/important.list'
def __init__(self,parent):
@ -263,17 +262,17 @@ class UpdateList():
def _make_groups_upgrade(self,cache,group_list, pkgs_upgrade = []):
try:
if os.path.isdir(self.INPUT_CONFIG_PATH) == False:
logging.warning("configPath(%s) is not exists...",self.INPUT_CONFIG_PATH)
if os.path.isdir(self.parent.config_path) == False:
logging.warning("configPath(%s) is not exists...",self.parent.config_path)
return
files = os.listdir(self.INPUT_CONFIG_PATH) #获得文件夹中所有文件的名称列表
files = os.listdir(self.parent.config_path) #获得文件夹中所有文件的名称列表
for ifile in files:
#判是否是目录以及是否以JSON结尾
if ifile.endswith('.json'):
#读取组JSON文件
with open(self.INPUT_CONFIG_PATH+ifile,'r') as f:
with open(self.parent.config_path+ifile,'r') as f:
try:
data = json.load(f)
except json.JSONDecodeError as exc:
@ -282,7 +281,7 @@ class UpdateList():
group_name = data['package']
#读取组的yaml 文件的changelog的信息
with open(self.INPUT_CONFIG_PATH + group_name + ".yaml", "r") as stream:
with open(self.parent.config_path + group_name + ".yaml", "r") as stream:
try:
data_yaml = yaml.safe_load(stream)
except yaml.YAMLError as exc:

View File

@ -24,8 +24,7 @@ class UpgradeConfig(SafeConfigParser):
# defaults are read first
self.config_files = []
if defaults_dir:
for cfg in glob.glob(defaults_dir + "/*.cfg"):
self.config_files.append(cfg)
self.config_files.append(os.path.join(datadir, defaults_dir))
# our config file
self.config_files += [maincfg]
# overrides are read later

View File

@ -7,7 +7,8 @@ __all__ = ("PKGS_INSTALL", "PKGS_REINSTALL", "PKGS_REMOVE", "PKGS_PURGE",
"EXIT_SUCCESS", "EXIT_CANCELLED", "EXIT_FAILED", "EXIT_UNFINISHED",
"ERROR_UPDATE_SOURCE_FAILED","ERROR_NETWORK_FAILED","ERROR_NOT_GROUPS_CONFIG","ERROR_SOFTWARE_INDEX_RROKEN",
"ERROR_NOT_INIT_PACKAGESINFIO","ERROR_READ_IMPORTANTLIST_FAILED",
"ERROR_NOT_INIT_PACKAGESINFIO","ERROR_READ_IMPORTANTLIST_FAILED","ERROR_RESOLVER_FAILED","ERROR_NOT_UPGRADE_PACKAGES",
"ERROR_REMOVE_ESSENTIAL_PACKAGES","ERROR_NOT_DISK_SPACE",
"ERROR_PACKAGE_DOWNLOAD_FAILED", "ERROR_REPO_DOWNLOAD_FAILED",
"ERROR_DEP_RESOLUTION_FAILED",
@ -51,7 +52,7 @@ __all__ = ("PKGS_INSTALL", "PKGS_REINSTALL", "PKGS_REMOVE", "PKGS_PURGE",
"get_role_localised_past_from_enum", "get_exit_string_from_enum",
"get_role_localised_present_from_enum", "get_role_error_from_enum",
"get_error_description_from_enum", "get_error_string_from_enum",
"get_status_string_from_enum", "get_download_status_from_enum")
"get_status_string_from_enum", "get_download_status_from_enum", "get_source_name_from_enum")
import gettext
gettext.bindtextdomain('kylin-system-updater', '/usr/share/locale')
@ -100,6 +101,12 @@ 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"
ERROR_RESOLVER_FAILED = "error-resolver-failed"
ERROR_NOT_UPGRADE_PACKAGES = "error-not-upgrade-packages"
ERROR_REMOVE_ESSENTIAL_PACKAGES = "error-remove-essential-packages"
ERROR_NOT_DISK_SPACE = "error-not-disk-space"
# ERROR CODES
#: Failed to download package files which should be installed.
@ -424,9 +431,10 @@ _DESCS_ERROR = {
"\"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"),
ERROR_PACKAGE_DOWNLOAD_FAILED: _("Check your Internet connection."),
ERROR_REPO_DOWNLOAD_FAILED: _("Check your Internet connection."),
@ -515,6 +523,10 @@ _STRINGS_ERROR = {
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"),
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"),
ERROR_PACKAGE_DOWNLOAD_FAILED: _("Failed to download package files"),
ERROR_REPO_DOWNLOAD_FAILED: _("Failed to download repository "
@ -605,6 +617,13 @@ STRINGS_DOWNLOAD = {
DOWNLOAD_IDLE: _("Idle"),
DOWNLOAD_NETWORK_ERROR: _("Network isn't available")}
SOURCE_NAME = {
'kylin-installer':_("Kylin Installer"),
'kylin-uninstaller':_("Kylin Uninstaller"),
'kylin-background-upgrade':_("Kylin Background Upgrade"),
'kylin-software-center':_("Kylin Software Center"),
}
def get_status_icon_name_from_enum(enum):
"""Get the icon name for a transaction status.
@ -749,4 +768,10 @@ def get_download_status_from_enum(enum):
except KeyError:
return None
def get_source_name_from_enum(enum):
try:
return SOURCE_NAME[enum]
except KeyError:
return _("Kylin System Updater")
# vim:ts=4:sw=4:et

View File

@ -289,6 +289,14 @@ def url_downloadable(uri, debug_func=None):
return False
return False
def emulate_calcul_broken(pkgs):
args = ["apt-get", "install","--simulate"]
args = args + pkgs
p = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True)
# logging.error(str(p.stdout))
return p.stdout
def is_chinese(string):
"""
检查整个字符串是否包含中文
@ -571,62 +579,6 @@ def get_broken_details(cache,now=True):
msg += dep_msg
return msg
def check_free_space(cache):
from .DistUpgradeCache import NotEnoughFreeSpaceError
err_sum = _("Not enough free disk space")
err_msg = _("The upgrade needs a total of %s free space on "
"disk '%s'. "
"Please free at least an additional %s of disk "
"space on '%s'. %s")
# specific ways to resolve lack of free space
remedy_archivedir = _("Remove temporary packages of former "
"installations using 'sudo apt clean'.")
remedy_boot = _("You can remove old kernels using "
"'sudo apt autoremove', and you could also "
"set COMPRESS=xz in "
"/etc/initramfs-tools/initramfs.conf to "
"reduce the size of your initramfs.")
remedy_root = _("Empty your trash and remove temporary "
"packages of former installations using "
"'sudo apt clean'.")
remedy_tmp = _("Reboot to clean up files in /tmp.")
remedy_usr = _("")
# check free space and error if its not enough
try:
cache.checkFreeSpace()
except NotEnoughFreeSpaceError as e:
# CheckFreeSpace examines where packages are cached
archivedir = apt_pkg.config.find_dir("Dir::Cache::archives")
err_long = ""
for req in e.free_space_required_list:
if err_long != "":
err_long += " "
if req.dir == archivedir:
err_long += err_msg % (req.size_total, req.dir,
req.size_needed, req.dir,
remedy_archivedir)
elif req.dir == "/boot":
err_long += err_msg % (req.size_total, req.dir,
req.size_needed, req.dir,
remedy_boot)
elif req.dir == "/":
err_long += err_msg % (req.size_total, req.dir,
req.size_needed, req.dir,
remedy_root)
elif req.dir == "/tmp":
err_long += err_msg % (req.size_total, req.dir,
req.size_needed, req.dir,
remedy_tmp)
elif req.dir == "/usr":
err_long += err_msg % (req.size_total, req.dir,
req.size_needed, req.dir,
remedy_usr)
#在此抛出异常
return False,err_sum
except SystemError:
logging.exception("free space check failed")
return True,''
def humanize_size(bytes):
"""

View File

@ -27,7 +27,7 @@ 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
from SystemUpdater.Core.utils import deb_verify,PolicyKit_Authority,get_proc_from_dbus_name
from .Core.errors import *
from .Core.enums import *
@ -46,7 +46,7 @@ class UpdateManager():
self.update_list = None
#表示后端的状态 注意:这个状态很重要 用不好整个后端代码就会卡住
self.now_working = InstallBackend.ACTION_DEFUALT_STATUS
self.config_path = self.check_config_patch()
#建立dbus
self.dbusController = self._setup_dbus()
@ -72,12 +72,25 @@ class UpdateManager():
#光盘源
self.source_info = UpdateSourceInfo()
self.update_essential = UpdateEssentialItem()
self.update_essential = UpdateEssentialItem(self)
self.install_mode = UpdateInstallMode(self)
self.refresh_cache()
def check_config_patch(self):
NOW_UPDATE_CONFIG = '/usr/share/kylin-update-desktop-config/config/'
OLD_UPDATE_CONFIG = '/usr/share/kylin-update-desktop-config/data/'
if os.path.exists(NOW_UPDATE_CONFIG):
self.config_path = NOW_UPDATE_CONFIG
return NOW_UPDATE_CONFIG
elif os.path.exists(OLD_UPDATE_CONFIG):
self.config_path = OLD_UPDATE_CONFIG
return OLD_UPDATE_CONFIG
else:
self.config_path = NOW_UPDATE_CONFIG
return NOW_UPDATE_CONFIG
def check_frontend_pkg(self):
#控制面板前端包的检查升级
if self.FRONTEND_PKG_NAME in self.cache:
@ -162,6 +175,8 @@ class UpdateManager():
try:
#每次更新之前 重新读取配置文件 刷新参数
self.configs.reReadConfigFiles()
self.check_config_patch()
self.retry_limit = self.RETRY_LIMIT_NUM
#检查安装的模式
@ -223,7 +238,6 @@ class UpdateManager():
except UpdateProgressExit as excep:
pass
except Exception as e:
logging.error(e)
def refresh_cache(self):
@ -434,6 +448,17 @@ class UpdateManager():
logging.error("Dbus has not withdrawn and retry reboot times:%d...",retry_reboot_times)
time.sleep(1)
def start_back_upgrade(self, pkglist, update_cache = False):
try:
if (update_cache):
update_backend = get_backend(self, InstallBackend.ACTION_UPDATE, InstallBackend.MODE_UPDATE_CACHE)
update_backend.start(partial_upgrade_list = pkglist)
else:
install_backend = get_backend(self, InstallBackend.ACTION_BACKGROUND_UPGRADE)
install_backend.start_alone(partial_upgrade_list = pkglist)
except Exception as e:
logging.error(str(e))
# 进行本地deb包安装的操作
def start_deb_install(self, deb_path = "", _check_local_dep = False, _auto_satisfy = False, sender=None):
# _check_local_dep : 是否查询本地依赖
@ -447,8 +472,9 @@ class UpdateManager():
self.dbusController.InstalldebFinished(False,'No such file or directory .','')
return
# 验签提权
sender_name = get_proc_from_dbus_name(sender)
if deb_verify(deb_path) != 0: #验签失败,提权
(status,error_string) = PolicyKit_Authority(_("Kylin System Updater requires authentication to install software packages."),sender)
(status,error_string) = PolicyKit_Authority(get_source_name_from_enum(sender_name)+_(" requires authentication to install software packages."),sender)
if not status:
self.dbusController.InstalldebFinished(False,error_string,'')
return
@ -743,15 +769,15 @@ class UpdateManager():
return _noSatisfyList
class UpdateEssentialItem():
READ_JSON_FILENAME = "/usr/share/kylin-update-desktop-config/data/kylin-update-desktop-system.json"
def __init__(self):
def __init__(self,parent):
self.essential_pkgs = []
self.read_path = parent.config_path + 'kylin-update-desktop-system.json'
self.update()
logging.info("Initialize Essential Packages List...")
def update(self):
if os.path.exists(self.READ_JSON_FILENAME):
with open(self.READ_JSON_FILENAME,'r') as f:
if os.path.exists(self.read_path):
with open(self.read_path,'r') as f:
try:
data = json.load(f)
self.essential_pkgs = data['install_list']
@ -759,16 +785,10 @@ class UpdateEssentialItem():
logging.error(exc)
def check(self,remove_pkgs):
header = ''
desc = ''
logging.info("Check: For remove of Essential Packages...")
for pkg in remove_pkgs:
if pkg in self.essential_pkgs:
header = _("There is an exception in the update package.")
desc = _("You request the removal of a system-essential package.")
return False,header,desc
return True,header,desc
raise UpdateBaseError(ERROR_REMOVE_ESSENTIAL_PACKAGES)
class UpdateSourceInfo():
DIR_MRDIA = "/media/"

View File

@ -14,6 +14,7 @@ from .Core.utils import humanize_size
from SystemUpdater.Core.utils import unLockedEnableShutdown,get_proc_from_dbus_name,PolicyKit_Authority
import locale
from xml.etree import ElementTree
from .Core.MyCache import MyCache
UPDATER_DBUS_INTERFACE = 'com.kylin.systemupgrade.interface'
UPDATER_DBUS_PATH = '/com/kylin/systemupgrade'
@ -350,7 +351,8 @@ class UpdateManagerDbusController(dbus.service.Object):
@dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='ass',out_signature='bs',sender_keyword='sender')
def PurgePackages(self,_purge_list,cur_user,sender=None):
try:
(status, details) = PolicyKit_Authority(_("Kylin System Updater requires authentication to uninstall software packages."), sender)
sender_name = get_proc_from_dbus_name(sender)
(status, details) = PolicyKit_Authority(get_source_name_from_enum(sender_name)+_(" requires authentication to uninstall software packages."), sender)
if not status:
self.PurgePackagesFinished(False,details,'')
return False,details
@ -369,7 +371,7 @@ class UpdateManagerDbusController(dbus.service.Object):
logging.warning('PurgePackages In the process of updating or Upgrading...')
return False,'PurgePackages In the process of updating or Upgrading...'
else:
sender_name = get_proc_from_dbus_name(sender)
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' DistPurgePackages Sender:%s and purge list is:%s...',sender_name,purge_list)
self._check_prohibit_user(sender_name)
@ -436,17 +438,6 @@ class UpdateManagerDbusController(dbus.service.Object):
logging.error("Database insert failedoptions:%svalue:%s" % (item, value))
return False
# # # download certain package and its dependencies
# @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='as', out_signature='b')
# def DownloadPackages(self, pkgs=[]):
# logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' DownloadPackages: %s',pkgs)
# try:
# self.parent.start_download(pkgs)
# return True
# except Exception as e:
# logging.error(e)
# return False
# 是否允许关机前更新
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='ss', out_signature='bs')
def UnattendedUpgradeValue(self, operation, value="false"):
@ -573,8 +564,8 @@ class UpdateManagerDbusController(dbus.service.Object):
self.parent.uuconfigs.setValue("autoUpgradePolicy", "autoUpgradeState", "on", True)
else :
self.parent.uuconfigs.setValue("autoUpgradePolicy", "autoUpgradeState", "off", True)
self.parent.uuconfigs.setValue("autoUpgradePolicy", "downloadMode", "manual", True)
self.parent.uuconfigs.setValue("autoUpgradePolicy", "installMode", "manual", True)
# self.parent.uuconfigs.setValue("autoUpgradePolicy", "downloadMode", "manual", True)
# self.parent.uuconfigs.setValue("autoUpgradePolicy", "installMode", "manual", True)
self.ChangeUpgradePolicy()
except Exception as e:
logging.error(str(e))
@ -731,7 +722,7 @@ class UpdateManagerDbusController(dbus.service.Object):
logging.warning("System version file doesn't exist.")
update_version,os_version = self.parent.sqlite3_server.get_default_version()
return os_version,update_version
os_version = str(self.parent.sqlite3_server.ucconfigs.get("SYSTEM","os_version"))
os_version = eval(str(self.parent.sqlite3_server.ucconfigs.get("SYSTEM","os_version")))
update_version = str(self.parent.sqlite3_server.ucconfigs.get("SYSTEM","update_version"))
except Exception as e:
logging.error(str(e))
@ -739,6 +730,42 @@ class UpdateManagerDbusController(dbus.service.Object):
logging.info('Current os_version: %s, release_id: %s .', os_version, update_version)
return os_version,update_version
# commitpackages
@dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='sasb',out_signature='b')
def InstallPkgs(self,source = "unKnown", pkg_list = [], update_cache = False):
try:
if update_cache:
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' InstallPkgs (UPDATE_CACHE).')
else:
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' InstallPkgs : [%s].', pkg_list)
self.parent.start_back_upgrade(pkg_list, update_cache)
except Exception as e:
logging.error(str(e))
return (False)
return True
# 检查更新
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='as', out_signature='as', sender_keyword='sender')
def CheckInstalledOrUpgrade(self, pkgs, sender=None):
# logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' CheckInstalledOrUpgrade Parsed silent upgrade ...')
try:
pkglist = []
cache = MyCache(None)
self.parent.collector.cache = cache
for i in pkgs:
name = str(i).strip().replace("\n", "")
if name in cache:
pkg = cache[name]
if pkg.is_installed == False or pkg.is_upgradable == True:
pkglist.append(pkg.name)
pkglist.append(str(pkg.candidate.size))
self.parent.collector.make_background_version(pkg)
self.parent.collector.background_upgradable.append(pkg.name)
except:
logging.error("CheckInstalledOrUpgrade: Failed to obtain package information: %s" % str(i), exc_info=True)
# logging.info("All silent upgrade: %s.",pkglist)
return pkglist
#更新进度信息 0~100 进度信息 101为非预期的信号
@dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='is')
def UpdateDetectStatusChanged(self,progress,status):

View File

@ -366,7 +366,7 @@ class InstallBackendAptdaemon(InstallBackend):
self.window_main.dbusController.FixBrokenStatusChanged(False,True,progress,status,'','')
elif action == self.ACTION_REMOVE_PACKAGES:
self.window_main.dbusController.PurgePkgStatusChanged(progress,status,details)
elif action == self.ACTION_INSTALL_DEB:
elif action == self.ACTION_INSTALL_DEB or action == self.ACTION_BACKGROUND_UPGRADE:
self.window_main.dbusController.InstalldebStatusChanged(progress,status,details)
else:
logging.info("Other Action:progress = %d , status = %s ,details = %s",progress,status,details)
@ -381,7 +381,7 @@ class InstallBackendAptdaemon(InstallBackend):
# eta 剩余时间不正确,取消掉
def _on_progress_download_changed(self,trans,current_items, total_items, currenty_bytes, total_bytes, current_cps, eta):
if self.action == self.ACTION_INSTALL or self.action == self.ACTION_DOWNLOADONLY:
if self.action == self.ACTION_INSTALL or self.action == self.ACTION_DOWNLOADONLY or self.action == self.ACTION_BACKGROUND_UPGRADE:
self.window_main.dbusController.UpdateDownloadInfo(\
self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs,\
current_items, total_items, \

View File

@ -8,10 +8,10 @@ import os
from gettext import gettext as _
import apt
import apt_pkg
import json
from SystemUpdater.Core.utils import (
unLockedEnableShutdown,
check_free_space,
get_broken_details
)
from SystemUpdater.Core.DataAcquisition import get_east_8_time
@ -19,6 +19,11 @@ from apt import Cache
import subprocess
from SystemUpdater.Core.UpdateList import LocalUpgradeDataList
from SystemUpdater.Core.errors import *
import threading
from SystemUpdater.Core.utils import emulate_calcul_broken
from SystemUpdater.Core.errors import *
from SystemUpdater.Core.enums import *
from SystemUpdater.Core.DistUpgradeCache import NotEnoughFreeSpaceError
class NowUpgradeMeta:
"""
@ -102,6 +107,7 @@ class InstallBackend():
ACTION_FIX_INCOMPLETE = 7
ACTION_CLEAN = 8
ACTION_INSTALL_SHUTDOWN = 9
ACTION_BACKGROUND_UPGRADE = 10
MODE_DEFAULT_STATUS = -1
@ -139,179 +145,154 @@ class InstallBackend():
self.now_upgrade = NowUpgradeMeta(parent=self)
def start(self,partial_upgrade_list = []):
_success = True
header = ''
desc = ''
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)
#安装升级包 首先必须调用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)
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))
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))
#当下载数量大于200个包时 就认为属于大版本升级 开启重试机制
if len(pkgs_install) + len(pkgs_upgrade) > 100:
logging.info("Open a major version upgrade and Retry mechanism on...")
self.now_upgrade.version_upgrade = True
#当下载数量大于200个包时 就认为属于大版本升级 开启重试机制
if len(pkgs_install) + len(pkgs_upgrade) > 100:
logging.info("Open a major version upgrade and Retry mechanism on...")
self.now_upgrade.version_upgrade = True
#检查是否存在可升级的包
if len(pkgs_install) == 0 and len(pkgs_upgrade) == 0 and len(pkgs_remove) == 0:
raise UpdateBaseError(ERROR_NOT_UPGRADE_PACKAGES)
#检查是否存在可升级的包
if len(pkgs_install) == 0 and len(pkgs_upgrade) == 0 and len(pkgs_remove) == 0:
header = _("There is an exception in the update package.")
desc = _("This update cannot detect the upgradeable package.")
self._action_done(self.action,False,False,header,desc)
return
if self.action_mode == self.MODE_INSTALL_SINGLE:
logging.info("MODE_INSTALL_SINGLE install:%s , upgrade:%s remove:%s",str(pkgs_install),str(pkgs_upgrade),str(pkgs_remove))
if len(pkgs_remove) > 0:
header = _("Exceptions of Priority Upgrade.")
desc = _("Due to the presence of deleted packages.")
self._action_done(self.action,False,False,header,desc)
return
success,header,desc = self.window_main.update_essential.check(pkgs_remove)
if success == False:
self._action_done(self.action,False,False,header,desc)
return
#检查磁盘的状态
_success,desc = check_free_space(self.cache)
if _success == False:
header = _("Disk space is insufficient, please clean the disk and then upgrade")
#当单包安装检查内存不够的时候,报错到控制面板 单包安装属于更新才使用的所以直接赋值为更新 再进行之后的报错处理
if self.action_mode == self.MODE_INSTALL_SINGLE:
self.action = self.ACTION_UPDATE
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)
#检查磁盘的状态
self.check_free_space(self.cache)
for ul in self.window_main.collector.upgrade_list:
self.window_main.collector.Upgrade_Process_Msg(self.action, {"appname":ul})
self._action_done(self.action,False,False,header,desc)
return
logging.info("Disk Check finished...")
self.window_main.collector.Upgrade_Process_Msg(self.action)
try:
if self.action == self.ACTION_INSTALL:
self.commit(self.action,pkgs_install, pkgs_upgrade, pkgs_remove)
elif self.action == self.ACTION_DOWNLOADONLY:
#将需要升级的软件包写入配置文件中进行保存
self._update_to_config(self.now_upgrade,pkgs_install,pkgs_upgrade,pkgs_remove)
self.commit(self.action,pkgs_install, pkgs_upgrade, pkgs_remove)
except Exception as e:
logging.error(e)
elif self.action == self.ACTION_INSTALL_SHUTDOWN:
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))
elif self.action == self.ACTION_INSTALL_SHUTDOWN:
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))
try:
#进度安装阶段标志位,使用鉴别是否出现安装过程中强制关闭 之后进行修复使用得
self.window_main.configs.setValue("SystemStatus","abnormal_reboot",str(True),True)
self.commit(self.action,pkgs_install, pkgs_upgrade, pkgs_remove)
except Exception as e:
logging.error(e)
#计算依赖解决方案
elif self.action == self.ACTION_CHECK_RESOLVER:
#被删除的包列表
delete_pkgs = []
#被删除包的描述
raw_description = []
#那些包升级导致删除包 全盘升级不包含
delete_desc = []
#计算依赖解决方案
elif self.action == self.ACTION_CHECK_RESOLVER:
#被删除的包列表
delete_pkgs = []
#被删除包的描述
raw_description = []
#那些包升级导致删除包 全盘升级不包含
delete_desc = []
#判断是否配置aptdaemon的限速
self.window_main.check_conifg_aptdeamon()
#判断是否配置aptdaemon的限速
self.window_main.check_conifg_aptdeamon()
if self.action_mode != self.MODE_INSTALL_SYSTEM:
#获取要升级的组列表
self.now_upgrade.make_upgrade_content(partial_upgrade_list)
#获取要升级和安装的包列表
pkgs_install,pkgs_upgrade = self._make_pkgs_list(self.cache,self.upgrade_data.groups_pkgs,self.now_upgrade.upgrade_groups,self.now_upgrade.single_pkgs)
#计算解决依赖关系
_success,delete_pkgs,delete_desc,header,desc = self._make_problem_resolver(self.cache,pkgs_install,pkgs_upgrade)
pkgs_install,pkgs_upgrade,pkgs_remove = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode)
if len(pkgs_remove) != len(delete_pkgs):
logging.warning("Simulation of the deletion package list:%s",str(delete_pkgs))
logging.warning("ProblemResolver of the deletion package list:%s",str(pkgs_remove))
delete_desc = []
else:
pkgs_remove = delete_pkgs
else:
# 使用全盘升级 全盘使用dist-upgrade
try:
if self.cache.get_changes():
self.cache.clear()
_success = self.cache._depcache.upgrade(True)
if self.action_mode != self.MODE_INSTALL_SYSTEM:
#获取要升级的组列表
self.now_upgrade.make_upgrade_content(partial_upgrade_list)
#获取要升级和安装的包列表
pkgs_install,pkgs_upgrade = self._make_pkgs_list(self.cache,self.upgrade_data.groups_pkgs,self.now_upgrade.upgrade_groups,self.now_upgrade.single_pkgs)
#计算解决依赖关系
delete_pkgs,delete_desc = self._make_problem_resolver(self.cache,pkgs_install,pkgs_upgrade)
pkgs_install,pkgs_upgrade,pkgs_remove = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode)
except Exception as e:
_success = False
desc = str(e)
logging.error(desc)
self.window_main.collector.Generate_Msg(self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs, self.action_mode)
self.window_main.collector.Upgrade_Process_Msg(self.action)
logging.info("RESOLVER install:%d , upgrade:%d remove:%d",len(pkgs_install),len(pkgs_upgrade),len(pkgs_remove))
is_remove_pkgs = len(pkgs_remove) != 0
if len(pkgs_remove) != len(delete_pkgs):
logging.warning("Simulation of the deletion package list:%s",str(delete_pkgs))
logging.warning("ProblemResolver of the deletion package list:%s",str(pkgs_remove))
delete_desc = []
else:
pkgs_remove = delete_pkgs
else:
# 使用全盘升级 全盘使用dist-upgrade
try:
if self.cache.get_changes():
self.cache.clear()
self.cache._depcache.upgrade(True)
except Exception as e:
logging.error(str(e))
raise UpdateBaseError(ERROR_RESOLVER_FAILED,desc= str(e))
pkgs_install,pkgs_upgrade,pkgs_remove = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode)
#添加关于删除包的描述信息
for pkg in pkgs_remove:
pkg_obj = self.cache[pkg]
# app = UpdateList.get_application_for_package(pkg_obj)
# if app is not None:
# raw_description.append(app.get_display_name())
# else:
raw_description.append(getattr(pkg_obj.candidate, "summary", ''))
#补充删除描述
if pkgs_remove != [] and delete_desc == []:
self.window_main.collector.Generate_Msg(self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs, self.action_mode)
for ul in self.window_main.collector.upgrade_list:
self.window_main.collector.Upgrade_Process_Msg(self.action, {"appname":ul})
logging.info("RESOLVER install:%d , upgrade:%d remove:%d",len(pkgs_install),len(pkgs_upgrade),len(pkgs_remove))
is_remove_pkgs = len(pkgs_remove) != 0
#添加关于删除包的描述信息
for pkg in pkgs_remove:
delete_desc.append('')
pkg_obj = self.cache[pkg]
raw_description.append(getattr(pkg_obj.candidate, "summary", ''))
#补充删除描述
if pkgs_remove != [] and delete_desc == []:
for pkg in pkgs_remove:
delete_desc.append('')
self.window_main.now_working = self.ACTION_DEFUALT_STATUS
if self.action_mode != self.MODE_INSTALL_SYSTEM:
self.window_main.dbusController.UpdateDependResloveStatus(True,is_remove_pkgs,pkgs_remove,raw_description,delete_desc,'','')
else:
self.window_main.dbusController.DistupgradeDependResloveStatus(True,is_remove_pkgs,pkgs_remove,raw_description,delete_desc,'','')
if self.action_mode != self.MODE_INSTALL_SYSTEM:
self.window_main.dbusController.UpdateDependResloveStatus(_success,is_remove_pkgs,pkgs_remove,raw_description,delete_desc,header,desc)
else:
self.window_main.dbusController.DistupgradeDependResloveStatus(_success,is_remove_pkgs,pkgs_remove,raw_description,delete_desc,header,desc)
#修复未满足的依赖关系 与apt-get -f install匹配
elif self.action == self.ACTION_FIX_BROKEN:
self.fix_broken()
# 修复不完整的安装dpkg configure -a
elif self.action == self.ACTION_FIX_INCOMPLETE:
self.fix_incomplete()
#卸载包
elif self.action == self.ACTION_REMOVE_PACKAGES:
try:
# 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)
self._action_done(self.action,False,True,'','')
# for pkg_obj in self.cache.get_changes():
# if pkg_obj.marked_delete:
# remove_pkgs.append(pkg_obj.name)
#修复未满足的依赖关系 与apt-get -f install匹配
elif self.action == self.ACTION_FIX_BROKEN:
self.fix_broken()
# 修复不完整的安装dpkg configure -a
elif self.action == self.ACTION_FIX_INCOMPLETE:
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)
# success,header,desc = self.check_essential_pkgs(remove_pkgs)
# if success == False:
# self._action_done(self.action,False,False,header,desc)
# return
# else:
# 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.purge_packages(partial_upgrade_list)
except Exception as e:
logging.error(desc)
#清空所有下载的文件
elif self.action == self.ACTION_CLEAN:
self.clean()
#更新cache
elif self.action == self.ACTION_UPDATE:
#检查依赖之前 判断是否需要重启aptdeamon 目前为了生效限速功能
self.window_main.check_conifg_aptdeamon()
self.update()
#清空所有下载的文件
elif self.action == self.ACTION_CLEAN:
self.clean()
#更新cache
elif self.action == self.ACTION_UPDATE:
#检查依赖之前 判断是否需要重启aptdeamon 目前为了生效限速功能
self.window_main.check_conifg_aptdeamon()
self.update()
except UpdateBaseError as excep:
self._action_done(self.action,True,False,excep.header,excep.desc)
except UpdateProgressExit as excep:
pass
except Exception as e:
logging.error(e)
def start_alone(self,partial_upgrade_list = [],_is_install = False):
# 安装本地deb包的接口
@ -320,6 +301,12 @@ class InstallBackend():
self.install_deb(install_path = partial_upgrade_list, install_force = _is_install)
except Exception as e:
logging.error(str(e))
elif self.action == self.ACTION_BACKGROUND_UPGRADE:
try:
pkgs_install = partial_upgrade_list
self.commit(self.ACTION_INSTALL,pkgs_install,[],[])
except Exception as e:
logging.error(str(e))
def update(self):
"""Run a update to refresh the package list"""
@ -456,13 +443,6 @@ class InstallBackend():
#将获取本次升级的包 进行计算依赖关系 解决依赖问题
def _make_problem_resolver(self,cache,pkgs_install = [],pkgs_upgrade = []):
_success = True
header = ''
desc = ''
#记录出现异常的包
exception_pkg = ''
last_broken_count = 0
#计算出来的需要删除的包列表
delete_pkgs = []
@ -480,7 +460,6 @@ class InstallBackend():
#标记计算所有需要安装的
for pkg in pkgs_upgrade + pkgs_install:
exception_pkg = pkg
pkg_cache = cache[pkg]
pkg_cache.mark_install(False, True, True)
@ -501,19 +480,21 @@ class InstallBackend():
delete_desc.extend(tmp_desc)
resolver.resolve()
return _success,delete_pkgs,delete_desc,header,desc
return delete_pkgs,delete_desc
except Exception as e:
_success = False
header = _("Could not calculate the upgrade")
logging.error(header + "(" + exception_pkg + ")" +str(e))
msg = get_broken_details(cache,False)
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')
desc ='\n' + msg
logging.error('\n' + msg)
return _success,[],[],header,desc
# logging.error('\n' + msg)
terminal_msg = emulate_calcul_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:
@ -630,7 +611,6 @@ class InstallBackend():
elif action == self.ACTION_INSTALL_SHUTDOWN:
self.window_main.configs.setValue("SystemStatus","abnormal_reboot",str(False))
#插入数据库
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)
@ -649,9 +629,27 @@ 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)
if self.action_mode != self.MODE_INSTALL_SYSTEM:
self.window_main.dbusController.UpdateDependResloveStatus(success,False,[''],[''],[''],error_string,error_desc)
else:
self.window_main.dbusController.DistupgradeDependResloveStatus(success,False,[''],[''],[''],error_string,error_desc)
elif action == self.ACTION_DOWNLOADONLY:
if self.now_upgrade.version_upgrade == True and self.now_upgrade.need_retry == True and success == False:
#增加重试次数的限制
if self.window_main.retry_limit != 0:
@ -663,6 +661,10 @@ class InstallBackend():
if success == True and self.action_mode == self.MODE_INSTALL_PARTIAL:
self.window_main.install_mode.tmp_content += self.now_upgrade.upgrade_content
if success == False:
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)
#如果下载成功 就标志需要 安装重启
if success == True:
#安装成功的话再获取关机锁
@ -714,6 +716,25 @@ class InstallBackend():
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:
UpdateMsg = {}
if success:
status = 'Success'
else:
status = 'Failed'
self.window_main.collector.Generate_Msg(self.window_main.collector.background_list, self.action_mode)
for bl in self.window_main.collector.background_list:
pkg = self.window_main.collector.cache[bl]
UpdateMsg.update({"appname":str(bl)})
UpdateMsg.update({"source":"Kylin Background upgrade"})
UpdateMsg.update({"status":str(status)})
UpdateMsg.update({"errorCode":str(error_string+" "+error_desc)})
if self.window_main.collector.background_version[bl]:
UpdateMsg.update({"old_version":self.window_main.collector.background_version[bl]})
UpdateMsg.update({"new_version":self.window_main.collector.cache[bl].candidate.source_version})
self.window_main.collector.Upgrade_Process_Msg(self.action, UpdateMsg.copy())
self.window_main.dbusController.UpdateInstallFinished(success,self.now_upgrade.upgrade_content,error_string,error_desc)
def _message_to_plymouth(self,message):
subprocess.call(["/bin/plymouth", "message", "--text", message])
@ -799,7 +820,7 @@ class InstallBackend():
#组的计算是否升级成功的方式 将组按照单包来计算的
if _now_upgrade.upgrade_groups != []:
pkgs_install,pkgs_upgrade = self._make_pkgs_list(self.cache,self.upgrade_data.groups_pkgs,_now_upgrade.upgrade_groups,[])
group_error_log = ''
# group_error_log = ''
install_error_pkgs = []
total_pkg = pkgs_install + pkgs_upgrade
@ -816,8 +837,8 @@ class InstallBackend():
else:
install_error_pkgs.append(pkg)
group_error_log = '\n'+ "This groups-package"+str(install_error_pkgs)+" is not install or upgrade" + '\n'
logging.warning(group_error_log)
# group_error_log = '\n'+ "This groups-package"+str(install_error_pkgs)+" is not install or upgrade" + '\n'
# logging.warning(group_error_log)
#如果没有
if total_pkg == []:
self.window_main.sqlite3_server.insert_info(self.action_mode,[],_now_upgrade.upgrade_groups,self.upgrade_data.adjust_pkgs,True,'', '')
@ -837,6 +858,63 @@ class InstallBackend():
except Exception as e:
logging.error(str(e))
def check_free_space(self,cache):
err_sum = _("Not enough free disk space")
err_msg = _("The upgrade needs a total of %s free space on "
"disk '%s'. "
"Please free at least an additional %s of disk "
"space on '%s'. %s")
# specific ways to resolve lack of free space
remedy_archivedir = _("Remove temporary packages of former "
"installations using 'sudo apt clean'.")
remedy_boot = _("You can remove old kernels using "
"'sudo apt autoremove', and you could also "
"set COMPRESS=xz in "
"/etc/initramfs-tools/initramfs.conf to "
"reduce the size of your initramfs.")
remedy_root = _("Empty your trash and remove temporary "
"packages of former installations using "
"'sudo apt clean'.")
remedy_tmp = _("Reboot to clean up files in /tmp.")
remedy_usr = _("")
# check free space and error if its not enough
try:
cache.checkFreeSpace()
except NotEnoughFreeSpaceError as e:
# CheckFreeSpace examines where packages are cached
archivedir = apt_pkg.config.find_dir("Dir::Cache::archives")
err_long = ""
for req in e.free_space_required_list:
if err_long != "":
err_long += " "
if req.dir == archivedir:
err_long += err_msg % (req.size_total, req.dir,
req.size_needed, req.dir,
remedy_archivedir)
elif req.dir == "/boot":
err_long += err_msg % (req.size_total, req.dir,
req.size_needed, req.dir,
remedy_boot)
elif req.dir == "/":
err_long += err_msg % (req.size_total, req.dir,
req.size_needed, req.dir,
remedy_root)
elif req.dir == "/tmp":
err_long += err_msg % (req.size_total, req.dir,
req.size_needed, req.dir,
remedy_tmp)
elif req.dir == "/usr":
err_long += err_msg % (req.size_total, req.dir,
req.size_needed, req.dir,
remedy_usr)
# #当单包安装检查内存不够的时候,报错到控制面板 单包安装属于更新才使用的所以直接赋值为更新 再进行之后的报错处理
if self.action_mode == self.MODE_INSTALL_SINGLE:
self.action = self.ACTION_UPDATE
raise UpdateBaseError(ERROR_NOT_DISK_SPACE,desc=err_sum)
except SystemError:
logging.exception("free space check failed")
logging.info("Disk Check finished...")
# try aptdaemon
if os.path.exists("/usr/sbin/aptd") \
and "UPDATE_MANAGER_FORCE_BACKEND_SYNAPTIC" not in os.environ:

View File

@ -0,0 +1,15 @@
[AutoUpgrade]
upgradelist =
[SystemStatus]
abnormal_reboot = False
close_source_filter = False
[ConfigPkgStatus]
check_resover_remove = False
check_frontend_pkg = True
[InstallMode]
shutdown_install = False
manual_install = False
auto_install = False

View File

@ -79,7 +79,7 @@ if __name__ == "__main__":
signal.signal(signal.SIGINT,signal_handler_term)
if options.debug:
logging.basicConfig(format=FORMAT,level=logging.DEBUG,datefmt='%m-%d,%H:%M:%S')
logging.basicConfig(format=FORMAT,level=logging.INFO,datefmt='%m-%d,%H:%M:%S')
else:
logging.basicConfig(format=FORMAT,level=logging.DEBUG,datefmt='%m-%d,%H:%M:%S',filename = logfile(),filemode = 'a')

View File

@ -8,3 +8,4 @@ SystemUpdater/Core/OriginFilter.py
SystemUpdater/Core/Database.py
SystemUpdater/UpdateManagerDbus.py
SystemUpdater/Core/utils.py
SystemUpdater/Core/enums.py

View File

@ -2556,9 +2556,6 @@ msgstr "%.0f kB"
msgid "Unable to access the source management server"
msgstr "无法访问源管理服务器,请稍后再试"
msgid "Connection exception with push server"
msgstr "推送服务器连接异常"
msgid "Check if your network requires authentication?"
msgstr "检查您的网络需要认证吗?"
@ -2686,3 +2683,31 @@ msgid ""
"Kylin System Updater requires authentication to uninstall software packages."
msgstr "麒麟更新器卸载软件包需要认证"
#: ../SystemUpdater/Core/enums.py:763
msgid "Kylin System Updater"
msgstr "麒麟更新器"
#: ../SystemUpdater/Core/enums.py:609
msgid "Kylin Installer"
msgstr "麒麟安装器"
#: ../SystemUpdater/Core/enums.py:610
msgid "Kylin Uninstaller"
msgstr "麒麟卸载器"
#: ../SystemUpdater/Core/enums.py:611
msgid "Kylin Background Upgrade"
msgstr "静默更新"
#: ../SystemUpdater/Core/enums.py:612
msgid "Kylin Software Center"
msgstr "软件商店"
#: ../SystemUpdater/UpdateManagerDbus.py:355
msgid " requires authentication to uninstall software packages."
msgstr "卸载软件包需要认证"
#. 验签失败,提权
#: ../SystemUpdater/UpdateManager.py:463
msgid " requires authentication to install software packages."
msgstr "安装软件包需要认证"

11
debian/changelog vendored
View File

@ -1,4 +1,13 @@
kylin-system-updater (2.0.3.1kord) v101; urgency=medium
kylin-system-updater (2.0.4.0kord) v101; urgency=medium
* BUG: 无
* 需求号: 无
* 其他改动说明: 可选更新通知机制优化
* 其他改动影响域:系统更新
-- luoxueyi <luoxueyi@kylinos.cn> Tue, 10 May 2022 19:13:31 +0800
kylin-system-updater (2.0.3.2kord) v101; urgency=medium
* BUG: 无
* 需求号: 无