Merge remote-tracking branch 'upstream/plugin_dev' into plugin_dev
This commit is contained in:
commit
f3de0f92e3
|
@ -25,7 +25,7 @@ LOCALTIDFILE = "tidfile.conf"
|
|||
MSGSNDDIR = "/var/lib/kylin-system-updater/sendinfos/"
|
||||
|
||||
class UpdateMsgCollector():
|
||||
def __init__(self, manager):
|
||||
def __init__(self, manager=None):
|
||||
self.UploadMessage = {}
|
||||
self.PackageInfo = {}
|
||||
self.waitSendList = []
|
||||
|
@ -63,7 +63,6 @@ class UpdateMsgCollector():
|
|||
# 获取本地tid
|
||||
self.sender.GetLocalTid()
|
||||
PackageInfo["tid"] = str(self.sender.localtid)
|
||||
logging.info("Get local tid:(%s).",self.sender.localtid)
|
||||
|
||||
json_PackageInfo = self.convertor.dictConvertJson(PackageInfo)
|
||||
|
||||
|
@ -110,6 +109,7 @@ class FormatConvert():
|
|||
|
||||
def dictConvertJson(self, dict_msg):
|
||||
#字典转换为json格式字符串
|
||||
json_file = ''
|
||||
try:
|
||||
json_file = json.dumps(dict_msg)
|
||||
except JSONDecodeError as e:
|
||||
|
@ -118,6 +118,7 @@ class FormatConvert():
|
|||
|
||||
def JsonConvertDict(self, json_file):
|
||||
# json格式字符串转换为字典
|
||||
dict_file = {}
|
||||
try:
|
||||
dict_file = json.loads(json_file)
|
||||
except JSONDecodeError as e:
|
||||
|
@ -170,7 +171,8 @@ class MessageSend():
|
|||
self.collector = UpdateMsgCollector()
|
||||
else:
|
||||
self.collector = DataCollector
|
||||
self.ReadFromFile("/var/lib/kylin-system-updater/sendinfos/testMsg.json")
|
||||
# self._ReadFromFile("/var/lib/kylin-system-updater/sendinfos/testMsg.json")
|
||||
# self._TimedTransmission()
|
||||
|
||||
def MsgSendToServer(self, UploadMessage, PackageInfo, encodeMsg):
|
||||
daqbus = dbus.SystemBus()
|
||||
|
@ -180,6 +182,18 @@ class MessageSend():
|
|||
except DBusException as e:
|
||||
logging.error(str(e))
|
||||
# 调用发送接口
|
||||
# PackageInfo = ("{\"messageType\":\"testDataa\",\"packageName\":\"testPack1\",\"tid\":\"HSx9qTy1TK3J06DRq7pkeTXptNEbVrDqq08yre+OLtE=\"}")
|
||||
# UploadMessage = ("{\"createTimeStamp\":\"2021-12-21 16:12:04.587\",\"myInt\":2}")
|
||||
# encodeMsg = ("fvlIx/KXjDIe3cbc1GMrs1FPRvqVBCt0LnrI1DSKYPc48e0pHPrkIwrSWISjrdu2Q7SqvlmrN9O3aGDKHBAyOovEtUPKKC18adfBQ6vDalhmHkHbrRhFwRrhDJ07PzTl8Lkw+hfW6eSAJ11LWqe00cNRRKgttfBM9IsHPJ82310KEwD3gieMVRwq1Zb9Ztc3hjP7mY0IhntffhRKnzou32A+dh8YT3B0jqQkEuMA2bOftEmDslKrspYSdV13Dj1QlPixiM6eF3G4sLSvcNwSwTG43e5eeqoWrsF0SE4hJUrLS/stGgX+2BabwZ9aX1Bsi+SQB+ZQy2uq5WEZcJO83w==")
|
||||
# print(PackageInfo)
|
||||
# PackageInfo = self.collector.convertor.JsonConvertDict(PackageInfo)
|
||||
# print(PackageInfo)
|
||||
# PackageInfo = self.collector.convertor.dictConvertJson(PackageInfo)
|
||||
# print(PackageInfo)
|
||||
# UploadMessage = self.collector.convertor.JsonConvertDict(UploadMessage)
|
||||
# print(UploadMessage)
|
||||
# UploadMessage = self.collector.convertor.dictConvertJson(UploadMessage)
|
||||
# print(UploadMessage)
|
||||
try:
|
||||
retval,retid = daqinterface.UploadMessage(PackageInfo, UploadMessage, encodeMsg)
|
||||
except AttributeError:
|
||||
|
@ -209,7 +223,7 @@ class MessageSend():
|
|||
result = "The createTimeStamp field of UploadedMessage is abnormal"
|
||||
logging.info("Sent Status: false - packageName: %s : result: %s.", PackageInfo['packageName'], result)
|
||||
# 上传失败写入本地json
|
||||
if retval != self.ERR_NO_LOACLTID:
|
||||
if retval != self.ERR_NO_LOACLTID or retval == self.ERR_NO_LOACLTID:
|
||||
self.WriteToJson(PackageInfo['messageType'], json_PackageInfo, json_UploadMessage, encodeMsg)
|
||||
elif retval == 0:
|
||||
result = "Send to server success"
|
||||
|
@ -258,13 +272,65 @@ class MessageSend():
|
|||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
def ReadFromFile(self, json_path):
|
||||
def _TimedTransmission(self, file_path = MSGSNDDIR):
|
||||
classify_list = [name for name in os.listdir(file_path) if name.endswith(".json")]
|
||||
for f in classify_list:
|
||||
# 循环发送每一个文件
|
||||
self._ReadFromFile(os.path.join(file_path, f))
|
||||
|
||||
def _ReadFromFile(self, json_path):
|
||||
new_lines = []
|
||||
# 从本地文件读取
|
||||
if not os.path.exists(json_path):
|
||||
return
|
||||
# with open(json_path, "w") as f:
|
||||
# while True:
|
||||
# line =
|
||||
with open(json_path, "r+") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# file is empty and path is exit -> remove file
|
||||
if len(lines) == 0 and os.path.exists(json_path):
|
||||
os.remove(json_path)
|
||||
return
|
||||
|
||||
#send installinfo or updateinfo
|
||||
for line in lines:
|
||||
(retval,retid) = self._file_send_server(line)
|
||||
if retval != 0: # success
|
||||
new_lines.append(line)
|
||||
if os.path.exists(json_path):
|
||||
os.remove(json_path)
|
||||
if len(new_lines) != 0:
|
||||
with open(json_path, "w+") as f:
|
||||
for line in lines:
|
||||
f.write(line)
|
||||
|
||||
def _file_send_server(self, json):
|
||||
UploadMessage = {}
|
||||
PackageInfo = {}
|
||||
encodeMsg = ''
|
||||
dict_msg = self.collector.convertor.JsonConvertDict(json)
|
||||
if 'UploadMessage' in dict_msg.keys():
|
||||
UploadMessage = dict_msg['UploadMessage']
|
||||
UploadMessage = self.collector.convertor.dictConvertJson(UploadMessage)
|
||||
if 'PackageInfo' in dict_msg.keys():
|
||||
PackageInfo = dict_msg['PackageInfo']
|
||||
PackageInfo = self.collector.convertor.dictConvertJson(PackageInfo)
|
||||
if 'encodeMsg' in dict_msg.keys():
|
||||
encodeMsg = str(dict_msg['encodeMsg'])
|
||||
if len(UploadMessage) == 0 or len(PackageInfo) == 0 or encodeMsg == '':
|
||||
logging.error("Msg error")
|
||||
return 6, ''
|
||||
daqbus = dbus.SystemBus()
|
||||
try:
|
||||
daqobj = daqbus.get_object('com.kylin.daq', '/com/kylin/daq')
|
||||
daqinterface = dbus.Interface(daqobj, dbus_interface='com.kylin.daq.interface')
|
||||
except DBusException as e:
|
||||
logging.error(str(e))
|
||||
try:
|
||||
retval,retid = daqinterface.UploadMessage(PackageInfo, UploadMessage, encodeMsg)
|
||||
except AttributeError:
|
||||
logging.error("Call UploadMessage: Attribute Error.")
|
||||
return (retval,retid)
|
||||
|
||||
|
||||
class UniqueKey():
|
||||
keyvalue = "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FR\
|
||||
|
@ -302,4 +368,4 @@ def get_east_8_time():
|
|||
if __name__ == "__name__":
|
||||
# 执行定时发送
|
||||
ms = MessageSend()
|
||||
ms.ReadFromFile("/var/lib/kylin-system-updater/sendinfos/testMsg.json")
|
||||
ms._ReadFromFile("/var/lib/kylin-system-updater/sendinfos/testMsg.json")
|
|
@ -164,7 +164,7 @@ class Sqlite3Server(object):
|
|||
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
json_file = json.dumps(UpdateInfos.copy())
|
||||
UpdateInfos.clear()
|
||||
self.window_main.collector.UpdateMsg("UpdateInfos", json_file)
|
||||
# self.window_main.collector.UpdateMsg("UpdateInfos", json_file)
|
||||
#安装信息install-infos
|
||||
InstallInfos.update({"packageName":str(pkgname)})
|
||||
if pkgname in self.window_main.update_list.local_upgrade_data.versoin_pkgs['groups_upgrade'].keys():
|
||||
|
@ -175,7 +175,7 @@ class Sqlite3Server(object):
|
|||
InstallInfos.update({"status":status})
|
||||
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
json_file = json.dumps(InstallInfos.copy())
|
||||
self.window_main.collector.UpdateMsg("InstallInfos", json_file)
|
||||
# self.window_main.collector.UpdateMsg("InstallInfos", json_file)
|
||||
elif pkg_list:
|
||||
# 单包更新 # 获取单包数据插入数据库
|
||||
pkgname = pkg_list.pop(0)
|
||||
|
@ -213,7 +213,7 @@ class Sqlite3Server(object):
|
|||
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
json_file = json.dumps(UpdateInfos.copy())
|
||||
UpdateInfos.clear()
|
||||
self.window_main.collector.UpdateMsg("UpdateInfos", json_file)
|
||||
# self.window_main.collector.UpdateMsg("UpdateInfos", json_file)
|
||||
#安装信息install-infos
|
||||
InstallInfos.update({"packageName":str(pkgname)})
|
||||
if pkgname in self.window_main.update_list.local_upgrade_data.versoin_pkgs['single_upgrade'].keys():
|
||||
|
@ -224,7 +224,7 @@ class Sqlite3Server(object):
|
|||
InstallInfos.update({"status":status})
|
||||
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
json_file = json.dumps(InstallInfos.copy())
|
||||
self.window_main.collector.UpdateMsg("InstallInfos", json_file)
|
||||
# self.window_main.collector.UpdateMsg("InstallInfos", json_file)
|
||||
|
||||
try:
|
||||
self.insert_into_updateinfo(pkgname, pkgversion, pkgdescription, timestr, status, "1", errstr)
|
||||
|
@ -257,7 +257,7 @@ class Sqlite3Server(object):
|
|||
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
json_file = json.dumps(UpdateInfos.copy())
|
||||
UpdateInfos.clear()
|
||||
self.window_main.collector.UpdateMsg("UpdateInfos", json_file)
|
||||
# self.window_main.collector.UpdateMsg("UpdateInfos", json_file)
|
||||
#安装信息install-infos
|
||||
InstallInfos.update({"packageName":str(pkg.name)})
|
||||
if pkg.name in self.window_main.update_list.local_upgrade_data.versoin_pkgs['groups_upgrade'].keys():
|
||||
|
@ -268,7 +268,7 @@ class Sqlite3Server(object):
|
|||
InstallInfos.update({"status":status})
|
||||
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
json_file = json.dumps(InstallInfos.copy())
|
||||
self.window_main.collector.UpdateMsg("InstallInfos", json_file)
|
||||
# self.window_main.collector.UpdateMsg("InstallInfos", json_file)
|
||||
|
||||
try:
|
||||
self.insert_into_updateinfo(str(i), pkgversion, pkgdescription, timestr, status, "1", errstr)
|
||||
|
@ -289,7 +289,7 @@ class Sqlite3Server(object):
|
|||
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
json_file = json.dumps(UpdateInfos.copy())
|
||||
UpdateInfos.clear()
|
||||
self.window_main.collector.UpdateMsg("UpdateInfos", json_file)
|
||||
# self.window_main.collector.UpdateMsg("UpdateInfos", json_file)
|
||||
#安装信息install-infos
|
||||
InstallInfos.update({"packageName":str(i)})
|
||||
if i in self.window_main.update_list.local_upgrade_data.versoin_pkgs['groups_upgrade'].keys():
|
||||
|
@ -300,7 +300,7 @@ class Sqlite3Server(object):
|
|||
InstallInfos.update({"status":status})
|
||||
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
json_file = json.dumps(InstallInfos.copy())
|
||||
self.window_main.collector.UpdateMsg("InstallInfos", json_file)
|
||||
# self.window_main.collector.UpdateMsg("InstallInfos", json_file)
|
||||
try:
|
||||
self.insert_into_updateinfo(str(i), pkgversion, pkgdescription, timestr, status, "1", errstr)
|
||||
group_list = []
|
||||
|
@ -328,7 +328,7 @@ class Sqlite3Server(object):
|
|||
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
json_file = json.dumps(UpdateInfos.copy())
|
||||
UpdateInfos.clear()
|
||||
self.window_main.collector.UpdateMsg("UpdateInfos", json_file)
|
||||
# self.window_main.collector.UpdateMsg("UpdateInfos", json_file)
|
||||
#安装信息install-infos
|
||||
InstallInfos.update({"packageName":str(pkg.name)})
|
||||
if pkg.name in self.window_main.update_list.local_upgrade_data.versoin_pkgs['groups_upgrade'].keys():
|
||||
|
@ -339,7 +339,7 @@ class Sqlite3Server(object):
|
|||
InstallInfos.update({"status":status})
|
||||
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
json_file = json.dumps(InstallInfos.copy())
|
||||
self.window_main.collector.UpdateMsg("InstallInfos", json_file)
|
||||
# self.window_main.collector.UpdateMsg("InstallInfos", json_file)
|
||||
try:
|
||||
self.insert_into_updateinfo(str(i), pkgversion, pkgdescription, timestr, status, "1", errstr)
|
||||
# 数据库文件被删除或者新增字段导致需要重新初始化数据库再写入
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
import os
|
||||
from gettext import gettext as _
|
||||
import apt
|
||||
import logging
|
||||
import fcntl
|
||||
import apt_pkg
|
||||
|
||||
|
||||
class LogInstallProgress(apt.progress.base.InstallProgress):
|
||||
""" Install progress that writes to self.progress_log
|
||||
(/var/run/unattended-upgrades.progress by default)
|
||||
"""
|
||||
def __init__(self,file):
|
||||
# type: (str) -> None
|
||||
apt.progress.base.InstallProgress.__init__(self)
|
||||
self.output_logfd = None # type: int
|
||||
self.filename=file
|
||||
self.error_pkg=""
|
||||
self.errormsg=""
|
||||
|
||||
def error(self,pkg, errormsg):
|
||||
logging.info(("errormsg:%s"),errormsg)
|
||||
self.error_pkg=self.filename
|
||||
self.errormsg = errormsg
|
||||
global error_status
|
||||
global error_msg
|
||||
error_status=1
|
||||
error_msg=errormsg
|
||||
|
||||
def status_change(self, pkg, percent, status):
|
||||
# type: (str, float, str) -> None
|
||||
logging.info(("pkg:%s,percent:%s,status:%s"),pkg,percent,status)
|
||||
with open(self.progress_log, "w") as f:
|
||||
f.write(("%s")%percent)
|
||||
f.write(_("当前进度: %s ,正在安装:%s,当前状态:%s") % (percent, pkg,status))
|
||||
f.write(_("Progress: %s %% (%s)") % (percent, pkg))
|
||||
|
||||
def _fixup_fds(self):
|
||||
# () -> None
|
||||
required_fds = [0, 1, 2, # stdin, stdout, stderr
|
||||
self.writefd,
|
||||
self.write_stream.fileno(),
|
||||
self.statusfd,
|
||||
self.status_stream.fileno()
|
||||
]
|
||||
# ensure that our required fds close on exec
|
||||
for fd in required_fds[3:]:
|
||||
old_flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC)
|
||||
# close all fds
|
||||
try:
|
||||
# PEP-446 implemented in Python 3.4 made all descriptors
|
||||
# CLOEXEC, but we need to be able to pass writefd to dpkg
|
||||
# when we spawn it
|
||||
os.set_inheritable(self.writefd, True)
|
||||
except AttributeError: # if we don't have os.set_inheritable()
|
||||
pass
|
||||
proc_fd = "/proc/self/fd"
|
||||
if os.path.exists(proc_fd):
|
||||
error_count = 0
|
||||
for fdname in os.listdir(proc_fd):
|
||||
try:
|
||||
fd = int(fdname)
|
||||
except Exception:
|
||||
print("ERROR: can not get fd for %s" % fdname)
|
||||
if fd in required_fds:
|
||||
continue
|
||||
try:
|
||||
os.close(fd)
|
||||
# print("closed: ", fd)
|
||||
except OSError as e:
|
||||
# there will be one fd that can not be closed
|
||||
# as its the fd from pythons internal diropen()
|
||||
# so its ok to ignore one close error
|
||||
error_count += 1
|
||||
if error_count > 1:
|
||||
print("ERROR: os.close(%s): %s" % (fd, e))
|
||||
|
||||
def _redirect_stdin(self):
|
||||
# type: () -> None
|
||||
REDIRECT_INPUT = os.devnull
|
||||
fd = os.open(REDIRECT_INPUT, os.O_RDWR)
|
||||
os.dup2(fd, 0)
|
||||
|
||||
def _redirect_output(self):
|
||||
# type: () -> None
|
||||
# do not create log in dry-run mode, just output to stdout/stderr
|
||||
if not apt_pkg.config.find_b("Debug::pkgDPkgPM", False):
|
||||
logfd = self._get_logfile_dpkg_fd()
|
||||
os.dup2(logfd, 1)
|
||||
os.dup2(logfd, 2)
|
||||
|
||||
def _get_logfile_dpkg_fd(self):
|
||||
# type: () -> int
|
||||
logfd = os.open(
|
||||
"/var/log/kylin-system-updater/kylin-system-updater.log.1", os.O_RDWR | os.O_APPEND | os.O_CREAT, 0o640)
|
||||
try:
|
||||
import grp
|
||||
adm_gid = grp.getgrnam("adm").gr_gid
|
||||
os.fchown(logfd, 0, adm_gid)
|
||||
except (KeyError, OSError):
|
||||
pass
|
||||
return logfd
|
||||
|
||||
def update_interface(self):
|
||||
# type: () -> None
|
||||
# call super class first
|
||||
apt.progress.base.InstallProgress.update_interface(self)
|
||||
|
||||
def _log_in_dpkg_log(self, msg):
|
||||
# type: (str) -> None
|
||||
logfd = self._get_logfile_dpkg_fd()
|
||||
os.write(logfd, msg.encode("utf-8"))
|
||||
os.close(logfd)
|
||||
|
||||
def finish_update(self):
|
||||
# type: () -> None
|
||||
# logging.info("finished")
|
||||
# if error_status == 1:
|
||||
# os._exit(1)
|
||||
pass
|
||||
|
||||
def fork(self):
|
||||
# type: () -> int
|
||||
pid = os.fork()
|
||||
if pid == 0:
|
||||
self._fixup_fds()
|
||||
self._redirect_stdin()
|
||||
self._redirect_output()
|
||||
return pid
|
|
@ -371,7 +371,23 @@ class OriginProperty():
|
|||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
class UnattendUpgradeFilter():
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
|
||||
def GetAllowOrigins(self):
|
||||
# 获取源属性
|
||||
self.origin_property = OriginProperty()
|
||||
self.origin_property.get_allowed_sources()
|
||||
self.origin_property.get_allowed_origin()
|
||||
|
||||
self.allowed_origins = get_allowed_origins(self.origin_property.allow_origin)
|
||||
|
||||
self.allowed_origins = deleteDuplicatedElementFromList(self.allowed_origins)
|
||||
logging.info(_("Allowed origins: %s"),
|
||||
self.allowed_origins)
|
||||
return self.allowed_origins
|
||||
|
||||
|
||||
def ver_in_allowed_origin(pkg, allow_origin):
|
||||
# type: (apt.Package, List[str]) -> apt.package.Version
|
||||
|
|
|
@ -103,11 +103,11 @@ class UpdateList():
|
|||
|
||||
if not os.path.exists(OUTPUT_CONFIG_PATH):
|
||||
os.makedirs(OUTPUT_CONFIG_PATH)
|
||||
logging.info('making the configuration file is complete...')
|
||||
logging.info('making the ConfigPath(%s) is complete...',OUTPUT_CONFIG_PATH)
|
||||
else:
|
||||
shutil.rmtree(OUTPUT_CONFIG_PATH)
|
||||
os.makedirs(OUTPUT_CONFIG_PATH)
|
||||
logging.info('Emptying the configuration file is complete...')
|
||||
logging.info('Emptying the ConfigPath(%s) is complete...',OUTPUT_CONFIG_PATH)
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
|
@ -276,21 +276,31 @@ class UpdateList():
|
|||
return [],[]
|
||||
|
||||
#输出白名单的配置
|
||||
def _make_white_config(self,cache,upgrade_data):
|
||||
def _make_autoupgrade_config(self,cache,upgrade_data,_adjust_pkgs):
|
||||
try:
|
||||
pkgs_install,pkgs_upgrade = self._make_pkgs_list(cache,upgrade_data.upgrade_groups_pkgs,upgrade_data.upgrade_groups,upgrade_data.single_pkgs)
|
||||
|
||||
split_adjust_pkgs = [i.split("=")[0] for i in _adjust_pkgs]
|
||||
|
||||
pkgs_upgrade_str = ''
|
||||
if pkgs_upgrade or pkgs_install:
|
||||
for pkg_str in pkgs_upgrade + pkgs_install:
|
||||
pkgs_list = pkgs_upgrade + pkgs_install
|
||||
if pkgs_list:
|
||||
for pkg_str in pkgs_list:
|
||||
|
||||
#记录源过滤后调整的版本
|
||||
if pkg_str in split_adjust_pkgs:
|
||||
pkg_str = _adjust_pkgs[split_adjust_pkgs.index(pkg_str)]
|
||||
else:
|
||||
ver = getattr(cache[pkg_str].candidate, "version", '')
|
||||
pkg_str = pkg_str + "=" + ver
|
||||
pkgs_upgrade_str += (pkg_str + ',')
|
||||
|
||||
pkgs_upgrade_str=pkgs_upgrade_str[:-1]
|
||||
|
||||
self.parent.configs.setValue("AutoUpgrade","upgradelist",pkgs_upgrade_str,True)
|
||||
logging.info("Generate Configfile to complete...")
|
||||
logging.info("Generate AutoUpgrade Configfile to Complete and Upgradable Number:%d...",len(pkgs_list))
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
logging.error(e)
|
||||
|
||||
def _make_groups_upgrade(self,cache,group_list, pkgs_upgrade = []):
|
||||
try:
|
||||
|
@ -508,7 +518,7 @@ class UpdateList():
|
|||
#分组的包的JSON
|
||||
self._make_groups_upgrade(cache,group_important_list,[pkg.name for pkg in pkgs_upgrade])
|
||||
|
||||
self._make_white_config(cache,self.local_upgrade_data)
|
||||
self._make_autoupgrade_config(cache,self.local_upgrade_data,self.local_upgrade_data.adjust_pkgs)
|
||||
#是否存在可升级的组
|
||||
if self.local_upgrade_data.upgrade_groups or self.local_upgrade_data.single_pkgs:
|
||||
return True,header,desc
|
||||
|
|
|
@ -416,12 +416,12 @@ def get_ubuntu_flavor(cache=None):
|
|||
return pkg.split('-', 1)[0]
|
||||
|
||||
|
||||
def _load_meta_pkg_list():
|
||||
# This could potentially introduce a circular dependency, but the config
|
||||
# parser logic is simple, and doesn't rely on any UpdateManager code.
|
||||
from DistUpgrade.DistUpgradeConfigParser import DistUpgradeConfig
|
||||
parser = DistUpgradeConfig('/usr/share/ubuntu-release-upgrader')
|
||||
return parser.getlist('Distro', 'MetaPkgs')
|
||||
# def _load_meta_pkg_list():
|
||||
# # This could potentially introduce a circular dependency, but the config
|
||||
# # parser logic is simple, and doesn't rely on any UpdateManager code.
|
||||
# from DistUpgrade.DistUpgradeConfigParser import DistUpgradeConfig
|
||||
# parser = DistUpgradeConfig('/usr/share/ubuntu-release-upgrader')
|
||||
# return parser.getlist('Distro', 'MetaPkgs')
|
||||
|
||||
|
||||
def get_ubuntu_flavor_package(cache=None):
|
||||
|
@ -431,10 +431,10 @@ def get_ubuntu_flavor_package(cache=None):
|
|||
# Lastly, fallback to ubuntu-desktop again.
|
||||
meta_pkgs = ['ubuntu-desktop']
|
||||
|
||||
try:
|
||||
meta_pkgs.extend(sorted(_load_meta_pkg_list()))
|
||||
except Exception as e:
|
||||
print('Could not load list of meta packages:', e)
|
||||
# try:
|
||||
# meta_pkgs.extend(sorted(_load_meta_pkg_list()))
|
||||
# except Exception as e:
|
||||
# print('Could not load list of meta packages:', e)
|
||||
|
||||
if cache is None:
|
||||
cache = apt.Cache()
|
||||
|
@ -787,8 +787,8 @@ def unLockedEnableShutdown():
|
|||
logging.error("unlock failed." + str(e))
|
||||
pidfile.close()
|
||||
pidfile = None
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
#print(mirror_from_sources_list())
|
||||
#print(on_battery())
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
# UpdateManager.py
|
||||
# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
|
||||
import apt
|
||||
import fcntl
|
||||
import os
|
||||
import subprocess
|
||||
from apt import Cache
|
||||
import apt_pkg
|
||||
import sys
|
||||
import time
|
||||
import shutil
|
||||
import dbus
|
||||
import logging
|
||||
|
@ -21,19 +22,18 @@ from .Core.Database import Sqlite3Server
|
|||
from .Core.loop import mainloop
|
||||
from .Core.DataAcquisition import UpdateMsgCollector
|
||||
|
||||
import time
|
||||
from gettext import gettext as _
|
||||
from SystemUpdater.backend import DownloadBackend as downb
|
||||
import apt_pkg
|
||||
from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
|
||||
from SystemUpdater.Core.utils import country_mirror, get_broken_details,get_lis_from_cache
|
||||
|
||||
import subprocess
|
||||
from SystemUpdater.Core.utils import get_broken_details,get_lis_from_cache
|
||||
from SystemUpdater.Core.DpkgInstallProgress import LogInstallProgress
|
||||
|
||||
class UpdateManager():
|
||||
SELF_PKG_NAME = 'kylin-system-updater'
|
||||
GROUPS_PKG_NAME = 'kylin-update-desktop-config'
|
||||
INSTALL_ALONE_PROGRESS = "alone"
|
||||
SOURCE_PARTS_PATH = "/etc/apt/"
|
||||
SOURCE_FILE_NAME = "sources.list"
|
||||
|
||||
def __init__(self,options):
|
||||
self.options = options
|
||||
|
@ -58,6 +58,9 @@ class UpdateManager():
|
|||
#数据采集器
|
||||
self.collector = UpdateMsgCollector(self)
|
||||
|
||||
#后台aptdaemon的语言环境
|
||||
self.aptdaemonLang = os.environ["LANGUAGE"]
|
||||
|
||||
|
||||
#检查是否需要重新启动aptdeamon 目前需要重启的有限速功能
|
||||
def restart_aptdeamon(self):
|
||||
|
@ -82,7 +85,7 @@ class UpdateManager():
|
|||
except Exception as e:
|
||||
logging.error(e)
|
||||
|
||||
#进行升级的操作
|
||||
#进行修复破损的包的操作 apt install -f
|
||||
def start_fix_broken(self):
|
||||
try:
|
||||
fix_backend = get_backend(self, InstallBackend.ACTION_FIX_BROKEN)
|
||||
|
@ -90,7 +93,7 @@ class UpdateManager():
|
|||
except Exception as e:
|
||||
logging.error(e)
|
||||
|
||||
#进行升级的操作
|
||||
#进行 dpkg --configure
|
||||
def start_fix_incomplete(self):
|
||||
try:
|
||||
fix_backend = get_backend(self, InstallBackend.ACTION_FIX_INCOMPLETE)
|
||||
|
@ -117,6 +120,28 @@ class UpdateManager():
|
|||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
#读取source.list 内容
|
||||
def _read_source_list(self):
|
||||
try:
|
||||
source_file_content = ''
|
||||
source_file_path = os.path.join(self.SOURCE_PARTS_PATH,self.SOURCE_FILE_NAME)
|
||||
with open(source_file_path) as source_file:
|
||||
source_file_content = source_file.read()
|
||||
return source_file_content
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return ''
|
||||
|
||||
#判断是否为光盘源
|
||||
def _is_disc_source(self):
|
||||
logging.info("Check: Whether to use CD-ROM source updates Successfully...")
|
||||
source_file_content = self._read_source_list()
|
||||
if "deb file:" in source_file_content:
|
||||
logging.info("Current use of CD-ROM source without network check...")
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
#进行更新的操作
|
||||
def start_update(self):
|
||||
_success = True
|
||||
|
@ -127,12 +152,23 @@ class UpdateManager():
|
|||
#每次更新之前 重新读取配置文件 刷新参数
|
||||
self.configs.reReadConfigFiles()
|
||||
|
||||
#进行检查网络
|
||||
self.dbusController.UpdateDetectStatusChanged(5,_("Checking network connection"))
|
||||
_success,header,desc = self.dbusController.check_connectivity()
|
||||
if _success == False:
|
||||
self.dbusController.DistUpdateDetectFinished(_success,[],header,desc)
|
||||
return
|
||||
#光盘源的话
|
||||
if self._is_disc_source() == True:
|
||||
logging.info("Turn off NetworkCheck and CloseFiter and UpdateSource...")
|
||||
#关闭网络检查
|
||||
self.options.no_check_network = True
|
||||
#当判断为光盘源时 关闭源过滤
|
||||
self.options.close_filter = True
|
||||
#关闭 更新源模板
|
||||
self.options.no_update_source = True
|
||||
|
||||
if self.options.no_check_network is False:
|
||||
#进行检查网络
|
||||
self.dbusController.UpdateDetectStatusChanged(5,_("Checking network connection"))
|
||||
_success,header,desc = self.dbusController.check_connectivity()
|
||||
if _success == False:
|
||||
self.dbusController.DistUpdateDetectFinished(_success,[],header,desc)
|
||||
return
|
||||
|
||||
#从服务器端更新摸板
|
||||
if self.options.no_update_source is False:
|
||||
|
@ -239,8 +275,6 @@ class UpdateManager():
|
|||
upgrade_list = self.update_list.local_upgrade_data.upgrade_groups + self.update_list.local_upgrade_data.single_pkgs
|
||||
#发送更新升级列表完成的标志
|
||||
self.dbusController.DistUpdateDetectFinished(_success,upgrade_list,header,desc)
|
||||
#检查安装完成之后需要重启吗
|
||||
self.is_reboot_required()
|
||||
#清空cache
|
||||
if self.cache != None and self.cache.get_changes():
|
||||
self.cache.clear()
|
||||
|
@ -290,9 +324,10 @@ class UpdateManager():
|
|||
self._check_cache_broken(self.cache)
|
||||
|
||||
#检查自己是否需要升级更新
|
||||
_success,header,desc = self._check_self_upgrade(self.cache)
|
||||
if _success == False:
|
||||
return _success,header,desc
|
||||
if self.options.no_check_selfupgrade is False:
|
||||
_success,header,desc = self._check_self_upgrade(self.cache)
|
||||
if _success == False:
|
||||
return _success,header,desc
|
||||
|
||||
#检查更新分组配置表
|
||||
_success,header,desc = self._check_group_config(self.cache)
|
||||
|
@ -399,11 +434,6 @@ class UpdateManager():
|
|||
|
||||
return _success,header,desc
|
||||
|
||||
def is_reboot_required(self):
|
||||
"""If a reboot is required to get all changes into effect."""
|
||||
return os.path.exists(os.path.join(apt_pkg.config.find_dir("Dir"),
|
||||
"var/run/reboot-required"))
|
||||
|
||||
def _check_cache_broken(self,cache):
|
||||
with cache.actiongroup():
|
||||
if cache.get_changes():
|
||||
|
@ -433,9 +463,7 @@ class UpdateManager():
|
|||
def _setup_dbus(self):
|
||||
# check if there is another g-a-i already and if not setup one
|
||||
# listening on dbus
|
||||
|
||||
bus = dbus.SystemBus()
|
||||
|
||||
try:
|
||||
bus_name = dbus.service.BusName(UPDATER_DBUS_SERVICE,
|
||||
bus,
|
||||
|
@ -447,15 +475,32 @@ class UpdateManager():
|
|||
logging.critical("Another daemon is already running")
|
||||
sys.exit(1)
|
||||
logging.warning("Replacing already running daemon")
|
||||
|
||||
retry_reboot_times = 0
|
||||
the_other_guy = bus.get_object(UPDATER_DBUS_SERVICE,
|
||||
UPDATER_DBUS_PATH)
|
||||
the_other_guy.Quit(dbus_interface=UPDATER_DBUS_INTERFACE,
|
||||
timeout=300)
|
||||
time.sleep(1)
|
||||
bus_name = dbus.service.BusName(UPDATER_DBUS_SERVICE,
|
||||
bus,
|
||||
do_not_queue=True)
|
||||
return UpdateManagerDbusController(self, bus_name)
|
||||
while True:
|
||||
retry_reboot_times = retry_reboot_times + 1
|
||||
#当重试次数超过5次时退出程序
|
||||
if retry_reboot_times > 5:
|
||||
logging.critical("Reboot backend is Failed...")
|
||||
sys.exit(1)
|
||||
try:
|
||||
bus_name = dbus.service.BusName(UPDATER_DBUS_SERVICE,
|
||||
bus,
|
||||
do_not_queue=True)
|
||||
logging.warning("Replacing already running daemon to Success...")
|
||||
return UpdateManagerDbusController(self, bus_name)
|
||||
except dbus.exceptions.NameExistsException:
|
||||
the_other_guy = bus.get_object(UPDATER_DBUS_SERVICE,
|
||||
UPDATER_DBUS_PATH)
|
||||
the_other_guy.Quit(dbus_interface=UPDATER_DBUS_INTERFACE,
|
||||
timeout=300)
|
||||
logging.error("Dbus has not withdrawn and retry reboot times:%d...",retry_reboot_times)
|
||||
time.sleep(1)
|
||||
|
||||
# 是否查找本地依赖
|
||||
def _attempt_depends(self,deb_cache, deb_path,_check_local_dep,_auto_satisfy, _install):
|
||||
|
@ -491,7 +536,7 @@ class UpdateManager():
|
|||
_local_satisfy = True
|
||||
elif not _auto_satisfy:
|
||||
_local_satisfy = False
|
||||
error_string = str(debname.split("_")[0])+" dependency is not satisfied. "
|
||||
error_string = str(debname.split("_")[0])+_("dependency is not satisfied")
|
||||
error_desc = ",".join(_install)
|
||||
logging.error(error_string+ error_desc)
|
||||
else:
|
||||
|
@ -509,14 +554,14 @@ class UpdateManager():
|
|||
elif not _check_local_dep and _auto_satisfy:
|
||||
_local_satisfy = True
|
||||
if _install:
|
||||
error_string = str(debname.split("_")[0])+" dependency is not satisfied, will download. "
|
||||
error_string = str(debname.split("_")[0])+_("dependency is not satisfied will download")
|
||||
error_desc = ",".join(_install)
|
||||
logging.error(error_string+error_desc)
|
||||
return _local_satisfy,error_string,error_desc
|
||||
elif not _check_local_dep and not _auto_satisfy:
|
||||
_local_satisfy = False
|
||||
if _install:
|
||||
error_string = str(debname.split("_")[0])+" dependency is not satisfied. "
|
||||
error_string = str(debname.split("_")[0])+_("dependency is not satisfied")
|
||||
error_desc = ",".join(_install)
|
||||
logging.error(error_string+error_desc)
|
||||
return _local_satisfy,error_string,error_desc
|
||||
|
@ -531,6 +576,7 @@ class UpdateManager():
|
|||
depends_list = []
|
||||
depends_pkg = []
|
||||
satisfy_list = []
|
||||
noSatisfyList = []
|
||||
depends_count = 0
|
||||
_status = False
|
||||
error_string = ''
|
||||
|
@ -542,7 +588,11 @@ class UpdateManager():
|
|||
if _check_local_dep: #查找本地
|
||||
# 需要查找本地依赖
|
||||
if len(self.noSatisfyList) > 0:
|
||||
noSatisfyList = [ str(nS[self.noSatisfyList.index(nS)][0]+'_'+nS[self.noSatisfyList.index(nS)][1]) for nS in self.noSatisfyList]
|
||||
for nS in self.noSatisfyList:
|
||||
if len(nS[0]) == 1:
|
||||
noSatisfyList.append(str(nS[0][0]))
|
||||
else :
|
||||
noSatisfyList.append(str(nS[0][0]))
|
||||
if len(_install) > 0:
|
||||
for pkg in deb_cache:
|
||||
if pkg.marked_install and pkg.name != str(debname.split("_")[0]):
|
||||
|
@ -553,18 +603,22 @@ class UpdateManager():
|
|||
depends_list = [debfile for debfile in os.listdir(absolute_path) if debfile.endswith(".deb")]
|
||||
for depends in depends_pkg:
|
||||
for debfile in depends_list:
|
||||
if "%3a" in debfile:
|
||||
debfile=debfile.replace("%3a",":")
|
||||
if depends.name in debfile and depends.candidate.version in debfile:
|
||||
depends_count += 1
|
||||
satisfy_list.append(debfile)
|
||||
for depends in noSatisfyList:
|
||||
for debfile in depends_list:
|
||||
if "%3a" in debfile:
|
||||
debfile=debfile.replace("%3a",":")
|
||||
if depends.split('_')[0] == debfile.split('_')[0] and depends.split('_')[1] == debfile.split('_')[1] and debfile not in satisfy_list:
|
||||
depends_count += 1
|
||||
satisfy_list.append(debfile)
|
||||
if depends_count < len(noSatisfyList):
|
||||
#本地依赖不满足
|
||||
_status = False
|
||||
error_string = str(debname.split("_")[0])+" dependency is not satisfied. "+",".join(noSatisfyList)
|
||||
error_string = str(debname.split("_")[0])+_("dependency is not satisfied")+", ".join(noSatisfyList)
|
||||
logging.error(error_string)
|
||||
header = error_string
|
||||
return False,header, desc
|
||||
|
@ -584,7 +638,7 @@ class UpdateManager():
|
|||
elif not _check_local_dep:
|
||||
_status = False
|
||||
if _install:
|
||||
error_string = str(debname.split("_")[0])+" dependency is not satisfied. "+",".join(_install)
|
||||
error_string = str(debname.split("_")[0])+_("dependency is not satisfied")+":".join(_install)
|
||||
logging.error(error_string)
|
||||
header = error_string
|
||||
return False,header, desc
|
||||
|
@ -626,7 +680,10 @@ class UpdateManager():
|
|||
# 需要降级
|
||||
try:
|
||||
pkg = deb_cache[debname.split('_')[0]]
|
||||
if pkg.is_installed and pkg.installed.source_version > debname.split('_')[1]:
|
||||
# 判断":"在版本号中的情况
|
||||
if "%3a" in debname:
|
||||
debname=debname.replace("%3a",":")
|
||||
if pkg.is_installed and (pkg.installed.source_version > debname.split('_')[1]):
|
||||
logging.info("Downgrade deb %s, from %s to %s.",\
|
||||
debname.split('_')[0], pkg.installed.source_version,debname.split('_')[1])
|
||||
self._need_downgrade = True
|
||||
|
@ -657,139 +714,38 @@ class UpdateManager():
|
|||
|
||||
def _gen_noSatisfyList(self, depends, deb_cache):
|
||||
_noSatisfyList = []
|
||||
_group_satify = False
|
||||
providers = []
|
||||
for or_group in depends:
|
||||
for deb in or_group:
|
||||
debname,ver,oper = deb
|
||||
if ":" in debname:
|
||||
debname=debname.split(":")[0]
|
||||
try:
|
||||
pkg = deb_cache[debname]
|
||||
if not pkg.installed or not apt_pkg.check_dep(pkg.installed.source_version, oper, ver):
|
||||
_noSatisfyList.append(or_group)
|
||||
if debname not in deb_cache:
|
||||
if deb_cache.is_virtual_package(debname):
|
||||
logging.warning("The cache has no package named '%s', this is a virtual package...", debname)
|
||||
providers = deb_cache.get_providing_packages(debname)
|
||||
# hear!
|
||||
if len(providers) != 1:
|
||||
logging.error("Can not found depend %s.", debname)
|
||||
continue
|
||||
depname = providers[0].name
|
||||
pkg = deb_cache[depname]
|
||||
cand = deb_cache._depcache.get_candidate_ver(pkg._pkg)
|
||||
if not cand:
|
||||
_group_satify = False
|
||||
if not apt_pkg.check_dep(cand.ver_str, oper, ver):
|
||||
_group_satify = False
|
||||
else:
|
||||
_group_satify = True
|
||||
else:
|
||||
pkg = deb_cache[debname]
|
||||
if pkg.installed and apt_pkg.check_dep(pkg.installed.source_version, oper, ver) and _group_satify == False:
|
||||
_group_satify = True
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
if _group_satify == False and or_group not in _noSatisfyList:
|
||||
_noSatisfyList.append(or_group)
|
||||
_group_satify = False
|
||||
return _noSatisfyList
|
||||
|
||||
|
||||
class LogInstallProgress(apt.progress.base.InstallProgress):
|
||||
""" Install progress that writes to self.progress_log
|
||||
(/var/run/unattended-upgrades.progress by default)
|
||||
"""
|
||||
def __init__(self,file):
|
||||
# type: (str) -> None
|
||||
apt.progress.base.InstallProgress.__init__(self)
|
||||
self.output_logfd = None # type: int
|
||||
self.filename=file
|
||||
self.error_pkg=""
|
||||
self.errormsg=""
|
||||
|
||||
def error(self,pkg, errormsg):
|
||||
logging.info(("errormsg:%s"),errormsg)
|
||||
self.error_pkg=self.filename
|
||||
self.errormsg = errormsg
|
||||
global error_status
|
||||
global error_msg
|
||||
error_status=1
|
||||
error_msg=errormsg
|
||||
|
||||
def status_change(self, pkg, percent, status):
|
||||
# type: (str, float, str) -> None
|
||||
logging.info(("pkg:%s,percent:%s,status:%s"),pkg,percent,status)
|
||||
with open(self.progress_log, "w") as f:
|
||||
f.write(("%s")%percent)
|
||||
f.write(_("当前进度: %s ,正在安装:%s,当前状态:%s") % (percent, pkg,status))
|
||||
f.write(_("Progress: %s %% (%s)") % (percent, pkg))
|
||||
|
||||
def _fixup_fds(self):
|
||||
# () -> None
|
||||
required_fds = [0, 1, 2, # stdin, stdout, stderr
|
||||
self.writefd,
|
||||
self.write_stream.fileno(),
|
||||
self.statusfd,
|
||||
self.status_stream.fileno()
|
||||
]
|
||||
# ensure that our required fds close on exec
|
||||
for fd in required_fds[3:]:
|
||||
old_flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC)
|
||||
# close all fds
|
||||
try:
|
||||
# PEP-446 implemented in Python 3.4 made all descriptors
|
||||
# CLOEXEC, but we need to be able to pass writefd to dpkg
|
||||
# when we spawn it
|
||||
os.set_inheritable(self.writefd, True)
|
||||
except AttributeError: # if we don't have os.set_inheritable()
|
||||
pass
|
||||
proc_fd = "/proc/self/fd"
|
||||
if os.path.exists(proc_fd):
|
||||
error_count = 0
|
||||
for fdname in os.listdir(proc_fd):
|
||||
try:
|
||||
fd = int(fdname)
|
||||
except Exception:
|
||||
print("ERROR: can not get fd for %s" % fdname)
|
||||
if fd in required_fds:
|
||||
continue
|
||||
try:
|
||||
os.close(fd)
|
||||
# print("closed: ", fd)
|
||||
except OSError as e:
|
||||
# there will be one fd that can not be closed
|
||||
# as its the fd from pythons internal diropen()
|
||||
# so its ok to ignore one close error
|
||||
error_count += 1
|
||||
if error_count > 1:
|
||||
print("ERROR: os.close(%s): %s" % (fd, e))
|
||||
|
||||
def _redirect_stdin(self):
|
||||
# type: () -> None
|
||||
REDIRECT_INPUT = os.devnull
|
||||
fd = os.open(REDIRECT_INPUT, os.O_RDWR)
|
||||
os.dup2(fd, 0)
|
||||
|
||||
def _redirect_output(self):
|
||||
# type: () -> None
|
||||
# do not create log in dry-run mode, just output to stdout/stderr
|
||||
if not apt_pkg.config.find_b("Debug::pkgDPkgPM", False):
|
||||
logfd = self._get_logfile_dpkg_fd()
|
||||
os.dup2(logfd, 1)
|
||||
os.dup2(logfd, 2)
|
||||
|
||||
def _get_logfile_dpkg_fd(self):
|
||||
# type: () -> int
|
||||
logfd = os.open(
|
||||
"/var/log/kylin-system-updater/kylin-system-updater.log.1", os.O_RDWR | os.O_APPEND | os.O_CREAT, 0o640)
|
||||
try:
|
||||
import grp
|
||||
adm_gid = grp.getgrnam("adm").gr_gid
|
||||
os.fchown(logfd, 0, adm_gid)
|
||||
except (KeyError, OSError):
|
||||
pass
|
||||
return logfd
|
||||
|
||||
def update_interface(self):
|
||||
# type: () -> None
|
||||
# call super class first
|
||||
apt.progress.base.InstallProgress.update_interface(self)
|
||||
|
||||
def _log_in_dpkg_log(self, msg):
|
||||
# type: (str) -> None
|
||||
logfd = self._get_logfile_dpkg_fd()
|
||||
os.write(logfd, msg.encode("utf-8"))
|
||||
os.close(logfd)
|
||||
|
||||
def finish_update(self):
|
||||
# type: () -> None
|
||||
# logging.info("finished")
|
||||
# if error_status == 1:
|
||||
# os._exit(1)
|
||||
pass
|
||||
|
||||
def fork(self):
|
||||
# type: () -> int
|
||||
pid = os.fork()
|
||||
if pid == 0:
|
||||
self._fixup_fds()
|
||||
self._redirect_stdin()
|
||||
self._redirect_output()
|
||||
return pid
|
||||
|
||||
|
|
@ -4,14 +4,14 @@ import dbus
|
|||
import dbus.service
|
||||
import logging
|
||||
|
||||
import apt_pkg
|
||||
import subprocess#snap
|
||||
from gettext import gettext as _
|
||||
from .backend import InstallBackend
|
||||
from .Core.loop import mainloop
|
||||
from .Core.utils import humanize_size
|
||||
from SystemUpdater.Core.utils import (
|
||||
unLockedEnableShutdown,
|
||||
)
|
||||
from SystemUpdater.Core.utils import unLockedEnableShutdown
|
||||
import locale
|
||||
|
||||
UPDATER_DBUS_INTERFACE = 'com.kylin.systemupgrade.interface'
|
||||
UPDATER_DBUS_PATH = '/com/kylin/systemupgrade'
|
||||
|
@ -42,8 +42,6 @@ COLORMETHOR_PREFIX = FRONT_COLOR_SEQ % CYAN
|
|||
class UpdateManagerDbusController(dbus.service.Object):
|
||||
""" this is a helper to provide the UpdateManagerIFace """
|
||||
|
||||
UPDATER_DBUS_INTERFACE = 'com.kylin.systemupgrade.interface'
|
||||
|
||||
def __init__(self, parent, bus_name,
|
||||
object_path=UPDATER_DBUS_PATH):
|
||||
dbus.service.Object.__init__(self, bus_name, object_path)
|
||||
|
@ -61,7 +59,7 @@ class UpdateManagerDbusController(dbus.service.Object):
|
|||
# logging.info("Start to update 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=5)
|
||||
retval = interface.updateSourceTemplate(timeout=20)
|
||||
except Exception as e:
|
||||
header = _("Unable to access the source management server")
|
||||
desc = str(e)
|
||||
|
@ -77,6 +75,16 @@ class UpdateManagerDbusController(dbus.service.Object):
|
|||
# logging.info("Update sourceTemplate successed...")
|
||||
return retval,header,desc
|
||||
|
||||
def is_reboot_required(self):
|
||||
"""If a reboot is required to get all changes into effect."""
|
||||
return os.path.exists(os.path.join(apt_pkg.config.find_dir("Dir"),
|
||||
"var/run/reboot-required"))
|
||||
|
||||
def is_logout_required(self):
|
||||
"""If a logout is required to get all changes into effect."""
|
||||
return os.path.exists(os.path.join(apt_pkg.config.find_dir("Dir"),
|
||||
"var/run/logout-required"))
|
||||
|
||||
#重启aptdeamon后台服务
|
||||
def make_aptdeamon_restart(self):
|
||||
header = ''
|
||||
|
@ -149,17 +157,13 @@ class UpdateManagerDbusController(dbus.service.Object):
|
|||
@dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='s',out_signature='i')
|
||||
def GetBackendStatus(self,user_lang):
|
||||
try:
|
||||
# if user_lang not in os.environ["LANG"]:
|
||||
# 如果系统不是中文也不是英文 就默认中文
|
||||
# if user_lang != "en" and user_lang != "zh_CN:en":
|
||||
# logging.error("%s",user_lang)
|
||||
# user_lang = "zh_CN:en"
|
||||
|
||||
# logging.warning("The system language is switched %s to %s",os.environ["LANGUAGE"],user_lang)
|
||||
# os.environ["LANGUAGE"] = user_lang
|
||||
|
||||
(lang, encoding) = locale._parse_localename(str(user_lang))
|
||||
#处于更新和升级中的话 不进行更新
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' GetBackendStatus ...')
|
||||
if lang != os.environ["LANGUAGE"]:
|
||||
logging.warning("The system language is switched %s to %s",os.environ["LANGUAGE"],lang)
|
||||
os.environ["LANGUAGE"] = lang
|
||||
|
||||
return self.parent.is_working
|
||||
except Exception:
|
||||
return False
|
||||
|
@ -338,12 +342,12 @@ class UpdateManagerDbusController(dbus.service.Object):
|
|||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='ss', sender_keyword='sender')
|
||||
def InsertInstallState(self, item, value, sender=None):
|
||||
try:
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' InsertInstallState, options:%s,value:%s' % (item, value))
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' InsertInstallState, options:%s,value:%s' % (item, value))
|
||||
self.parent.sqlite3_server.insert_into_display(item, value)
|
||||
logging.info("Database inserted successfully,options:%s,value:%s" % (item, value))
|
||||
logging.info("Database inserted successfully,options:%s,value:%s" % (item, value))
|
||||
return True
|
||||
except Exception as e:
|
||||
logging.error("Database insert failed,options:%s,value:%s" % (item, value))
|
||||
logging.error("Database insert failed,options:%s,value:%s" % (item, value))
|
||||
return False
|
||||
|
||||
# # download certain package and its dependencies
|
||||
|
@ -431,6 +435,61 @@ class UpdateManagerDbusController(dbus.service.Object):
|
|||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
# dbus接口:安装本地snap包
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='b', sender_keyword='sender')
|
||||
def InstallSnap(self, path, sender=None):
|
||||
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+" Install Snap Packages(%s)...",path)
|
||||
try:
|
||||
status= subprocess.getstatusoutput("snap install " +path+" --dangerous")
|
||||
except Exception as e:
|
||||
logging.error("Install Snap Packages occur error:%s",str(e))
|
||||
msg = {"statue": "Fail", "errorcode": str(0), "error_message": _("Command execution error")}
|
||||
kwarg = {"error_message": str(msg)}
|
||||
|
||||
self.KumSnapSignal("snap_error", kwarg)
|
||||
return False
|
||||
|
||||
#安装成功
|
||||
if status[0]==0:
|
||||
logging.info("Install Snap Packages(%s) is success",path)
|
||||
msg = {"statue": "Success", "errorcode": str(0), "error_message": ""}
|
||||
kwarg = {"action": str(msg)}
|
||||
self.KumSnapSignal("snap_finish", kwarg)
|
||||
return True
|
||||
else:
|
||||
#失败之后的处理
|
||||
logging.info("Install Snap Packages(%s) is Failed",path)
|
||||
if "supported architectures" in status[1]:
|
||||
logging.error("Supported architectures does not match")
|
||||
msg = {"statue": "Fail", "errorcode": str(0), "error_message": _("Unsupported architecture")}
|
||||
else:
|
||||
logging.error("Other Error...")
|
||||
msg = {"statue": "Fail", "errorcode": str(0), "error_message": _("Other Error")}
|
||||
kwarg = {"error_message": str(msg)}
|
||||
|
||||
self.KumSnapSignal("snap_error", kwarg)
|
||||
return False
|
||||
|
||||
# 监控是否需要重启的操作
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='b')
|
||||
def CheckRebootRequired(self, model):
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' CheckRebootRequired is be %s',str(model))
|
||||
try:
|
||||
#更新完成之后检查是否需要重启
|
||||
if self.is_reboot_required() == True:
|
||||
self.RebootLogoutRequired("reboot")
|
||||
logging.info("System need to Reboot...")
|
||||
elif self.is_logout_required() == True:
|
||||
self.RebootLogoutRequired("logout")
|
||||
logging.info("System need to Logout...")
|
||||
else:
|
||||
logging.info("System not need to Reboot or Logout...")
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return False
|
||||
return True
|
||||
|
||||
#更新进度信息 0~100 进度信息 101为非预期的信号
|
||||
@dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='is')
|
||||
def UpdateDetectStatusChanged(self,progress,status):
|
||||
|
@ -471,7 +530,7 @@ class UpdateManagerDbusController(dbus.service.Object):
|
|||
#查询解决依赖 信号
|
||||
@dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bbasasasss')
|
||||
def UpdateDependResloveStatus(self, resolver_status, remove_status,remove_pkgs,pkg_raw_description,delete_desc,error_string='',error_desc=''):
|
||||
logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" UpdateDependResloveStatus:resolver_status = %r , resolver_status = %r , remove_pkgs = %a,pkg_raw_description = %s ,delete_desc = %s,error_string = %s , error_desc = %s ",\
|
||||
logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" UpdateDependResloveStatus:resolver_status = %r , remove_status = %r , remove_pkgs = %a,pkg_raw_description = %s ,delete_desc = %s,error_string = %s , error_desc = %s ",\
|
||||
resolver_status,remove_status,remove_pkgs,pkg_raw_description,delete_desc,error_string,error_desc)
|
||||
|
||||
#查询dist-upgrade解决依赖
|
||||
|
@ -517,49 +576,17 @@ class UpdateManagerDbusController(dbus.service.Object):
|
|||
success,error_string,error_desc)
|
||||
|
||||
#安装进度信息 0~100 进度信息 101为非预期的信号
|
||||
@dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bss')
|
||||
@dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='iss')
|
||||
def InstalldebStatusChanged(self,progress,status,current_details):
|
||||
logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" InstalldebStatusChanged progress = %d , status = %s ,current_details = %s",\
|
||||
progress,status,current_details)
|
||||
|
||||
|
||||
# dbus接口:安装本地snap包
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='b', sender_keyword='sender')
|
||||
def InstallSnap(self, path, sender=None):
|
||||
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+" InstallSnap Install Path = %s...",path)
|
||||
try:
|
||||
status= subprocess.getstatusoutput("snap install " +path+" --dangerous")
|
||||
except Exception as e:
|
||||
logging.error("Install Snap Packages occur error:%s",str(e))
|
||||
msg = {"statue": "Fail", "errorcode": str(0), "error_message": _("Command execution error")}
|
||||
kwarg = {"error_message": str(msg)}
|
||||
|
||||
self.KumSnapSignal("snap_error", kwarg)
|
||||
return False
|
||||
|
||||
#安装成功
|
||||
if status[0]==0:
|
||||
logging.info("Install Snap Packages(%s) is success",path)
|
||||
msg = {"statue": "Success", "errorcode": str(0), "error_message": ""}
|
||||
kwarg = {"action": str(msg)}
|
||||
self.KumSnapSignal("snap_finish", kwarg)
|
||||
return True
|
||||
else:
|
||||
#失败之后的处理
|
||||
logging.info("Install Snap Packages(%s) is Failed",path)
|
||||
if "supported architectures" in status[1]:
|
||||
logging.error("Supported architectures does not match")
|
||||
msg = {"statue": "Fail", "errorcode": str(0), "error_message": _("Unsupported architecture")}
|
||||
else:
|
||||
logging.error("Other Error...")
|
||||
msg = {"statue": "Fail", "errorcode": str(0), "error_message": _("Other Error")}
|
||||
kwarg = {"error_message": str(msg)}
|
||||
|
||||
self.KumSnapSignal("snap_error", kwarg)
|
||||
return False
|
||||
|
||||
# dbus 信号:用于发送本地安装snap包的结果
|
||||
@dbus.service.signal(UPDATER_DBUS_INTERFACE, signature='sa{sv}')
|
||||
def KumSnapSignal(self, type_msg, msg):
|
||||
logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" KumSnapSignal type_msg = %s,msg = %s",type_msg,str(msg))
|
||||
|
||||
#重启和注销请求信号
|
||||
@dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='s')
|
||||
def RebootLogoutRequired(self,required_status=''):
|
||||
logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " RebootLogoutRequired required_status = %s",required_status)
|
|
@ -1,5 +1,16 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import aptdaemon.client as client
|
||||
import aptdaemon.errors as errors
|
||||
import aptdaemon.enums as enums
|
||||
from aptdaemon.enums import (
|
||||
EXIT_SUCCESS,
|
||||
EXIT_FAILED,
|
||||
EXIT_CANCELLED,
|
||||
get_error_description_from_enum,
|
||||
get_error_string_from_enum,
|
||||
get_status_string_from_enum
|
||||
)
|
||||
from defer import inline_callbacks
|
||||
from SystemUpdater.backend import InstallBackend
|
||||
import logging
|
||||
|
@ -7,6 +18,8 @@ from gettext import gettext as _
|
|||
from SystemUpdater.Core.utils import humanize_size
|
||||
import dbus,time
|
||||
from gi.repository import GLib
|
||||
import os
|
||||
from importlib import reload
|
||||
|
||||
# 超时检测 秒单位
|
||||
UPDATER_IDLE_CHECK_INTERVAL = 10
|
||||
|
@ -22,23 +35,13 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
def __init__(self, window_main, action):
|
||||
InstallBackend.__init__(self, window_main, action)
|
||||
self.window_main = window_main
|
||||
|
||||
from aptdaemon import client
|
||||
from aptdaemon import errors
|
||||
from aptdaemon.enums import (EXIT_SUCCESS,
|
||||
EXIT_FAILED,
|
||||
EXIT_CANCELLED,
|
||||
get_error_description_from_enum,
|
||||
get_error_string_from_enum,
|
||||
get_status_string_from_enum
|
||||
)
|
||||
self.errors = errors
|
||||
self.EXIT_SUCCESS = EXIT_SUCCESS
|
||||
self.EXIT_FAILED = EXIT_FAILED
|
||||
self.EXIT_CANCELLED = EXIT_CANCELLED
|
||||
self.get_error_description_from_enum = get_error_description_from_enum
|
||||
self.get_error_string_from_enum = get_error_string_from_enum
|
||||
self.get_status_string_from_enum = get_status_string_from_enum
|
||||
#切换aptdaemon的语言 重新导入模块就可以进行切换
|
||||
if os.environ["LANGUAGE"] != self.window_main.aptdaemonLang:
|
||||
logging.warning("Aptdeamon language is switched %s to %s",self.window_main.aptdaemonLang,os.environ["LANGUAGE"])
|
||||
self.window_main.aptdaemonLang = os.environ["LANGUAGE"]
|
||||
reload(client)
|
||||
reload(errors)
|
||||
reload(enums)
|
||||
|
||||
#客户端连接aptdeamon的dbus接口
|
||||
self.client = client.AptClient()
|
||||
|
@ -116,7 +119,7 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_UPDATE,
|
||||
_("Checking for updates…"), False)
|
||||
except self.errors.NotAuthorizedError:
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_UPDATE,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
|
@ -138,11 +141,11 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
|
||||
yield self._show_transaction(trans, self.ACTION_INSTALL,
|
||||
_("Installing updates…"), True)
|
||||
except self.errors.NotAuthorizedError:
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_INSTALL,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
except self.errors.TransactionFailed as e:
|
||||
except errors.TransactionFailed as e:
|
||||
self.trans_failed_msg = str(e)
|
||||
except dbus.DBusException as e:
|
||||
if e.get_dbus_name() != "org.freedesktop.DBus.Error.NoReply":
|
||||
|
@ -164,7 +167,7 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_INSTALL_DEB,
|
||||
_("Installing deb packages…"), False)
|
||||
except self.errors.NotAuthorizedError:
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_INSTALL_DEB,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
|
@ -184,7 +187,7 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_FIX_BROKEN,
|
||||
_("Installing deb packages…"), False)
|
||||
except self.errors.NotAuthorizedError:
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_FIX_BROKEN,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
|
@ -203,7 +206,7 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_FIX_INCOMPLETE,
|
||||
_("fix incomplete install"), False)
|
||||
except self.errors.NotAuthorizedError:
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_FIX_INCOMPLETE,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
|
@ -222,7 +225,7 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_CLEAN,
|
||||
_("Remove all downloaded files."), False)
|
||||
except self.errors.NotAuthorizedError:
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_CLEAN,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
|
@ -241,7 +244,7 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_DOWNLOADONLY,
|
||||
_("Downloading deb packages…"), False)
|
||||
except self.errors.NotAuthorizedError:
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_DOWNLOADONLY,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
|
@ -260,15 +263,15 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_REMOVE_PACKAGES,
|
||||
_("Installing deb packages…"), False)
|
||||
except self.errors.NotAuthorizedError:
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_REMOVE_PACKAGES,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
# self._action_done(self.ACTION_REMOVE_PACKAGES,
|
||||
# is_cancelled=False, success=False,
|
||||
# error_string='', error_desc='')
|
||||
self._action_done(self.ACTION_REMOVE_PACKAGES,
|
||||
is_cancelled=False, success=False,
|
||||
error_string=str(e), error_desc='')
|
||||
|
||||
#进度回调
|
||||
def _on_progress_changed(self, trans,progress,action):
|
||||
|
@ -290,7 +293,7 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
#同步状态回调
|
||||
def _on_status_changed(self, trans, status,action):
|
||||
#转化词条
|
||||
self.trans_status = self.get_status_string_from_enum(status)
|
||||
self.trans_status = get_status_string_from_enum(status)
|
||||
self._dist_status_changed(action,self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs,\
|
||||
self.trans_progress,self.trans_status,self.details)
|
||||
|
||||
|
@ -360,7 +363,7 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
|
||||
#增加记录当产生错误的时候 详细信息
|
||||
def _on_error_changed(self, trans,error_code, error_details):
|
||||
# error_string = self.get_error_string_from_enum(error_code)
|
||||
# error_string = get_error_string_from_enum(error_code)
|
||||
self.trans_error_details = str(error_details)
|
||||
logging.error(str(error_details))
|
||||
|
||||
|
@ -377,7 +380,7 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
trans.connect("progress-details-changed", self._on_progress_download_changed)
|
||||
trans.connect("status-details-changed", self._on_details_changed)
|
||||
trans.connect("error", self._on_error_changed)
|
||||
# yield trans.set_debconf_frontend("ukui")
|
||||
# yield trans.set_locale(os.environ["LANGUAGE"] + ".UTF-8")
|
||||
yield trans.run()
|
||||
|
||||
def _on_finished(self, trans, status, action):
|
||||
|
@ -386,29 +389,29 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
|
||||
#退出
|
||||
self.on_install_stage = False
|
||||
if status == self.EXIT_FAILED:
|
||||
error_string = self.get_error_string_from_enum(trans.error.code)
|
||||
error_desc = self.get_error_description_from_enum(trans.error.code)
|
||||
if status == EXIT_FAILED:
|
||||
error_string = get_error_string_from_enum(trans.error.code)
|
||||
error_desc = get_error_description_from_enum(trans.error.code)
|
||||
if self.trans_failed_msg:
|
||||
error_desc = error_desc + "\n" + self.trans_failed_msg
|
||||
#取消下载
|
||||
elif status == self.EXIT_CANCELLED:
|
||||
elif status == EXIT_CANCELLED:
|
||||
error_string = _("Failed to fetch")
|
||||
error_desc = _("_Cancel Upgrade")
|
||||
elif status == self.EXIT_SUCCESS and action == self.ACTION_INSTALL:
|
||||
elif status == EXIT_SUCCESS and action == self.ACTION_INSTALL:
|
||||
error_string = _("System upgrade is complete.")
|
||||
elif status == self.EXIT_SUCCESS and action == self.ACTION_REMOVE_PACKAGES:
|
||||
elif status == EXIT_SUCCESS and action == self.ACTION_REMOVE_PACKAGES:
|
||||
error_string = _("Uninstallation completed")
|
||||
|
||||
is_success = (status == self.EXIT_SUCCESS)
|
||||
is_success = (status == EXIT_SUCCESS)
|
||||
try:
|
||||
self._action_done(action,
|
||||
is_cancelled=(status == self.EXIT_CANCELLED), success=is_success,
|
||||
is_cancelled=(status == EXIT_CANCELLED), success=is_success,
|
||||
error_string=error_string, error_desc=error_desc)
|
||||
except TypeError:
|
||||
# this module used to be be lazily imported and in older code
|
||||
# trans_failed= is not accepted
|
||||
# TODO: this workaround can be dropped in Ubuntu 20.10
|
||||
self._action_done(action,
|
||||
is_cancelled=(status == self.EXIT_CANCELLED), success=is_success,
|
||||
is_cancelled=(status == EXIT_CANCELLED), success=is_success,
|
||||
error_string=error_string, error_desc=error_desc)
|
||||
|
|
|
@ -7,7 +7,7 @@ import logging
|
|||
import os
|
||||
from gettext import gettext as _
|
||||
|
||||
import apt_pkg
|
||||
import apt
|
||||
from SystemUpdater.Core.utils import (
|
||||
unLockedEnableShutdown,
|
||||
check_free_space,
|
||||
|
@ -95,7 +95,7 @@ class InstallBackend():
|
|||
|
||||
if len(pkgs_install) == 0 and len(pkgs_upgrade) == 0 and len(pkgs_remove) == 0:
|
||||
#FIXME: 没有需要升级和安装的包 检查升级包是否不存在本次升级
|
||||
header = _("There are no packages that need to be upgraded and installed")
|
||||
header = _("Resolve the dependency exception,there is no package that needs to be upgrade,please check the package status.")
|
||||
desc = _("Check if the upgrade package does not exist for this upgrade")
|
||||
self._action_done(self.action,True,False,header,desc)
|
||||
return
|
||||
|
@ -330,14 +330,19 @@ class InstallBackend():
|
|||
with cache.actiongroup():
|
||||
if cache.get_changes():
|
||||
cache.clear()
|
||||
Fix = apt_pkg.ProblemResolver(cache._depcache)
|
||||
resolver = apt.cache.ProblemResolver(cache)
|
||||
|
||||
#计算出来的需要删除的包列表
|
||||
all_delete_pkgs = []
|
||||
all_delete_desc = []
|
||||
#标记计算所有需要升级的包
|
||||
for pkg in pkgs_upgrade:
|
||||
cache[pkg].mark_upgrade()
|
||||
#mark_install (auto_fix: bool = True, auto_inst: bool = True, from_user: bool = True)
|
||||
cache[pkg].mark_install(True, False, True)
|
||||
|
||||
resolver.clear(cache[pkg])
|
||||
resolver.protect(cache[pkg])
|
||||
|
||||
deleted_pkgs = self._make_delete_pkgs(cache,all_delete_pkgs)
|
||||
for d_pkg in deleted_pkgs:
|
||||
delete_desc = str(d_pkg) + _(" Will be deleted Due to Upgrade ") + str(pkg)
|
||||
|
@ -346,14 +351,17 @@ class InstallBackend():
|
|||
|
||||
#标记计算所有需要安装的
|
||||
for pkg in pkgs_install:
|
||||
cache[pkg].mark_install()
|
||||
cache[pkg].mark_install(True, False,True)
|
||||
|
||||
resolver.clear(cache[pkg])
|
||||
resolver.protect(cache[pkg])
|
||||
deleted_pkgs = self._make_delete_pkgs(cache,all_delete_pkgs)
|
||||
for d_pkg in deleted_pkgs:
|
||||
delete_desc = str(d_pkg) + _(" Will be deleted Due to Install ") + str(pkg)
|
||||
all_delete_desc.append(delete_desc)
|
||||
logging.warning(delete_desc)
|
||||
#会安装新包和卸载包
|
||||
Fix.resolve()
|
||||
resolver.resolve()
|
||||
#不会安装和卸载 只升级
|
||||
return _success,all_delete_pkgs,all_delete_desc,header,desc
|
||||
except Exception as e:
|
||||
|
@ -430,6 +438,9 @@ class InstallBackend():
|
|||
self.cache.clear()
|
||||
|
||||
self.window_main.dbusController.UpdateInstallFinished(success,upgrade_content,error_string,error_desc)
|
||||
|
||||
if success:
|
||||
self.window_main.dbusController.CheckRebootRequired("self")
|
||||
|
||||
elif action == self.ACTION_UPDATE:
|
||||
if success == False and 'The following signatures' in self.trans_error_details:
|
||||
|
|
|
@ -26,3 +26,6 @@ Kylin-system-updater::ImportantListDir "/var/lib/kylin-software-properties/templ
|
|||
|
||||
Dir::Bin::Methods::ftp "ftp";
|
||||
|
||||
DPkg::Options{
|
||||
"--force-confnew";
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
|
||||
# a) it breaks if its not available
|
||||
# b) the string we have here does not need it (because it has no vars)
|
||||
eval_gettext() {
|
||||
if [ -x /usr/bin/gettext ]; then
|
||||
echo $(gettext "$1")
|
||||
else
|
||||
echo "$1"
|
||||
fi
|
||||
}
|
||||
export TEXTDOMAIN=update-notifier
|
||||
export TEXTDOMAINDIR=/usr/share/locale
|
||||
|
||||
case "$DPKG_MAINTSCRIPT_PACKAGE::$DPKG_MAINTSCRIPT_NAME" in
|
||||
linux-image-extra*::postrm)
|
||||
exit 0;;
|
||||
esac
|
||||
|
||||
if [ "$0" = "/etc/kernel/postinst.d/update-notifier" ]; then
|
||||
DPKG_MAINTSCRIPT_PACKAGE=linux-base
|
||||
fi
|
||||
|
||||
# Wake the applet up
|
||||
echo "*** $(eval_gettext "System logout required") ***" > /var/run/logout-required
|
||||
echo "$DPKG_MAINTSCRIPT_PACKAGE" >> /var/run/logout-required.pkgs
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
|
||||
# a) it breaks if its not available
|
||||
# b) the string we have here does not need it (because it has no vars)
|
||||
eval_gettext() {
|
||||
if [ -x /usr/bin/gettext ]; then
|
||||
echo $(gettext "$1")
|
||||
else
|
||||
echo "$1"
|
||||
fi
|
||||
}
|
||||
export TEXTDOMAIN=update-notifier
|
||||
export TEXTDOMAINDIR=/usr/share/locale
|
||||
|
||||
case "$DPKG_MAINTSCRIPT_PACKAGE::$DPKG_MAINTSCRIPT_NAME" in
|
||||
linux-image-extra*::postrm)
|
||||
exit 0;;
|
||||
esac
|
||||
|
||||
if [ "$0" = "/etc/kernel/postinst.d/update-notifier" ]; then
|
||||
DPKG_MAINTSCRIPT_PACKAGE=linux-base
|
||||
fi
|
||||
|
||||
# Wake the applet up
|
||||
echo "*** $(eval_gettext "System restart required") ***" > /var/run/reboot-required
|
||||
echo "$DPKG_MAINTSCRIPT_PACKAGE" >> /var/run/reboot-required.pkgs
|
|
@ -40,7 +40,7 @@
|
|||
| PurgePackages | as | b | 卸载软件包 | |
|
||||
| InstalldebFile | ssbb | b | 安装本地deb包 | |
|
||||
| DataBackendCollect | ss | b | | |
|
||||
| | | | | |
|
||||
| CheckRebootRequired | s | b | 检查是否需要重启的方法,以及弹窗提示 | |
|
||||
### Method分析
|
||||
|
||||
#### UpdateDetect
|
||||
|
@ -182,6 +182,14 @@
|
|||
|
||||
|
||||
|
||||
#### CheckRebootRequired
|
||||
|
||||
- `介绍:` 检查是否需要重启的方法,以及弹窗提示
|
||||
- `入参`: `s:`标识那个应用调的此接口(如自动更新可填入字符串“autoyupgrade”)
|
||||
- `出参:`True or False 执行的结果
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Signal列表
|
||||
|
@ -200,7 +208,7 @@
|
|||
| FixBrokenStatusChanged | iiisss | 修复依赖的状态信号 |
|
||||
| PurgePackagesFinished | iss | 卸载完成信号 |
|
||||
| PurgePkgStatusChanged | bss | 卸载进度信息以及状态信息 |
|
||||
| | | |
|
||||
| RebootLogoutRequired | s | 请求重启或者注销的信号 |
|
||||
| | | |
|
||||
|
||||
|
||||
|
@ -271,7 +279,7 @@
|
|||
|
||||
- `介绍:` 升级安装完成的信号
|
||||
|
||||
- `出参`: `b:`升级是否成功, `b:`是否需要重启,`as:`可升级的组列表,`s:`产生错误的结果,`s:`产生错误的原因
|
||||
- `出参`: `b:`升级是否成功,`as:`可升级的组列表,`s:`产生错误的结果,`s:`产生错误的原因
|
||||
|
||||
- `示例:`
|
||||
|
||||
|
@ -367,13 +375,30 @@
|
|||
InstalldebFinished success = True , error_string = , error_desc =
|
||||
|
||||
#安装失败 缺少依赖的
|
||||
InstalldebFinished success = False , error_string = bandit dependency is not satisfied. , error_desc = python3-bandit
|
||||
InstalldebFinished success = False , error_string = bandit dependency is not satisfied , error_desc = python3-bandit
|
||||
|
||||
#安装失败 选择从网络拉依赖 网络断开 报网络错误
|
||||
InstalldebFinished success = False , error_string = 下载软件包文件失败 , error_desc = 检查您的网络连接。
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### RebootLogoutRequired
|
||||
|
||||
- `介绍:`请求重启和注销的信号
|
||||
|
||||
- `出参`: `s:` "reboot" 表示重启 "logout"表示注销
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
Emitting RebootLogoutRequired required_status = reboot
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -42,17 +42,25 @@ if __name__ == "__main__":
|
|||
help=_("Do not check for updates source when updating"))
|
||||
parser.add_option ("--no-update", action="store_true",
|
||||
dest="no_update", default=False,
|
||||
help=_("Do not check for updates when starting"))
|
||||
help="Do not check for updates when starting")
|
||||
parser.add_option("-c", "--close-filter",
|
||||
default=False,
|
||||
action="store_true", dest="close_filter",
|
||||
help=_("Quit and close allowed_origin"))
|
||||
help=_("Quit and close allowed origin"))
|
||||
parser.add_option("--no-check-network",
|
||||
default=False,
|
||||
action="store_true", dest="no_check_network",
|
||||
help=_("Quit and close check network"))
|
||||
|
||||
parser.add_option("--no-check-selfupgrade",
|
||||
default=False,
|
||||
action="store_true", dest="no_check_selfupgrade",
|
||||
help=_("no check self(kylin-system-updater) upgrade"))
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if os.getuid() != 0:
|
||||
print(_("You need to be root to run this application"))
|
||||
|
||||
sys.exit(1)
|
||||
|
||||
# set debconf to NON_INTERACTIVE
|
||||
|
@ -60,6 +68,16 @@ if __name__ == "__main__":
|
|||
os.environ["TERM"] = "xterm"
|
||||
os.environ["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
#当不存在语言变量时 默认显示中文
|
||||
if not "LANGUAGE" in os.environ:
|
||||
os.environ["LANGUAGE"] = "zh_CN"
|
||||
|
||||
#做一些规范处理
|
||||
if os.environ["LANGUAGE"] == "en":
|
||||
os.environ["LANGUAGE"] = "en_US"
|
||||
if os.environ["LANGUAGE"] == "zh_CN:en":
|
||||
os.environ["LANGUAGE"] = "zh_CN"
|
||||
|
||||
# ensure that we are not killed when the terminal goes away e.g. on
|
||||
# shutdown
|
||||
signal.signal(signal.SIGHUP, signal.SIG_IGN)
|
||||
|
@ -69,22 +87,12 @@ if __name__ == "__main__":
|
|||
logging.basicConfig(format=FORMAT,level=logging.DEBUG,datefmt='%m-%d,%H:%M:%S')
|
||||
else:
|
||||
logging.basicConfig(format=FORMAT,level=logging.DEBUG,datefmt='%m-%d,%H:%M:%S',filename = logfile(),filemode = 'a')
|
||||
|
||||
#目前 多用户的语言切换还未做好 不启用
|
||||
# if sys.getfilesystemencoding() == "ascii" and not "LANG" in os.environ:
|
||||
# logging.info('start setting environ["LANG"] ...')
|
||||
# os.environ["LANG"] = "C.UTF-8"
|
||||
# os.execv(sys.argv[0], sys.argv)
|
||||
|
||||
# if not "LANGUAGE" in os.environ:
|
||||
# os.environ["LANGUAGE"] = "zh_CN.UTF-8"
|
||||
|
||||
# logging.info('kylin-system-updater(lang:%s) starting ...',os.environ["LANGUAGE"])
|
||||
logging.info('kylin-system-updater starting ...')
|
||||
logging.info('kylin-system-updater(lang:%s) starting ...',os.environ["LANGUAGE"])
|
||||
|
||||
app = UpdateManager(options)
|
||||
|
||||
#当出现安装过程中异常的重启时 直接开机直接进行修复操作
|
||||
#当出现安装过程中异常的重启时 开机直接进行修复操作
|
||||
if app.configs.getWithDefault("SystemStatus", "isabnormalreboot", False) == True:
|
||||
app.start_update()
|
||||
|
||||
|
|
|
@ -2569,8 +2569,8 @@ msgstr "获取推送出现异常,请稍后再试"
|
|||
msgid "You need to be root to run this application"
|
||||
msgstr "你需要root权限运行"
|
||||
|
||||
msgid "There are no packages that need to be upgraded and installed"
|
||||
msgstr "没有需要升级和安装的包"
|
||||
msgid "Resolve the dependency exception,there is no package that needs to be upgrade,please check the package status."
|
||||
msgstr "解决依赖关系存在异常,没有需要升级的软件包,请检查软件包状态。"
|
||||
|
||||
msgid "Check if the upgrade package does not exist for this upgrade"
|
||||
msgstr "检查升级包是否不存在本次升级"
|
||||
|
@ -2593,6 +2593,12 @@ msgstr "架构不符合"
|
|||
msgid "Other Error"
|
||||
msgstr "其他错误"
|
||||
|
||||
msgid "dependency is not satisfied"
|
||||
msgstr "依赖关系不满足"
|
||||
|
||||
msgid "dependency is not satisfied will download"
|
||||
msgstr "依赖关系不满足"
|
||||
|
||||
msgid "Disk space is insufficient, please clean the disk and then upgrade"
|
||||
msgstr "磁盘空间不足,请清理磁盘后进行升级更新"
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ domain=kylin-system-updater
|
|||
formats = bztar
|
||||
|
||||
[nosetests]
|
||||
match=^test
|
||||
match=test
|
||||
|
||||
[install]
|
||||
skip-build=0
|
||||
|
|
|
@ -1,10 +1,148 @@
|
|||
kylin-system-updater (1.3.1kord) v101; urgency=medium
|
||||
|
||||
* BUG: wu
|
||||
kylin-system-updater (1.4.6.1kord) v101; urgency=medium
|
||||
|
||||
* BUG: 无
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 增加重启弹窗
|
||||
* 其他改动影响域:系统更新
|
||||
|
||||
-- luoxueyi <luoxueyi@kylinos.cn> Tue, 18 Jan 2022 21:45:30 +0800
|
||||
|
||||
kylin-system-updater (1.4.6kord) v101; urgency=medium
|
||||
|
||||
* BUG: #102463: 【自动更新】自动更新时源优先级策略未生效,实际获取所有源中最高版本而非按照设置的优先级顺序获取包,导致包版本下载错误
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 无
|
||||
* 其他改动影响域:系统更新
|
||||
|
||||
-- luoxueyi <luoxueyi@kylinos.cn> Tue, 18 Jan 2022 21:45:30 +0800
|
||||
|
||||
kylin-system-updater (1.4.5kord) v101; urgency=medium
|
||||
|
||||
* BUG: #102442 【系统更新】【PTOF】系统更新过程重启控制面板,页面展示内容为上次更新时间并持续停留在此页面,此时不能获取更新列表进行更新操作
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 无
|
||||
* 其他改动影响域:系统更新
|
||||
|
||||
-- luoxueyi <luoxueyi@kylinos.cn> Fri, 14 Jan 2022 20:38:07 +0800
|
||||
|
||||
kylin-system-updater (1.4.4kord) v101; urgency=medium
|
||||
|
||||
* BUG: 无
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 增加自适应更新的安装重启提示
|
||||
* 其他改动影响域:系统更新
|
||||
|
||||
-- luoxueyi <luoxueyi@kylinos.cn> Wed, 12 Jan 2022 21:34:56 +0800
|
||||
|
||||
kylin-system-updater (1.4.3kord) v101; urgency=medium
|
||||
|
||||
* BUG: #94805 【更新升级-需求-9002】【系统更新】更新页面上方文字与图标未对齐
|
||||
#101985【更新】系统字号为15,点击查看历史设备,左上角“历史更新”字样未随系统字号改变而改变
|
||||
#101669【自适应更新】【自动更新】自动更新过滤掉了非正式源,只能获取archive正式源的包,其余源的更新内容不能获取到
|
||||
#102069【安装器】无法安装360助手等三方软件且报错不满足依赖,使用dpkg命令可以成功安装且不需要安装其他依赖
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 无
|
||||
* 其他改动影响域:系统更新
|
||||
|
||||
-- luoxueyi <luoxueyi@kylinos.cn> Mon, 10 Jan 2022 18:11:55 +0800
|
||||
|
||||
kylin-system-updater (1.4.1.5kord) v101; urgency=medium
|
||||
|
||||
* BUG: #94805 【更新升级-需求-9002】【系统更新】更新页面上方文字与图标未对齐
|
||||
#101985【更新】系统字号为15,点击查看历史设备,左上角“历史更新”字样未随系统字号改变而改变
|
||||
#101333【控制面板】【更新】系统语言为英文,系统字号为15,系统主题为默认,升级页面自动下载与安装更新悬浮框背景为黑色
|
||||
#101669【自适应更新】【自动更新】自动更新过滤掉了非正式源,只能获取archive正式源的包,其余源的更新内容不能获取到
|
||||
#102069【安装器】无法安装360助手等三方软件且报错不满足依赖,使用dpkg命令可以成功安装且不需要安装其他依赖
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 无
|
||||
* 其他改动影响域:系统更新
|
||||
|
||||
-- luoxueyi <luoxueyi@kylinos.cn> Mon, 10 Jan 2022 18:11:55 +0800
|
||||
|
||||
kylin-system-updater (1.4.1.1kord) v101; urgency=medium
|
||||
|
||||
* BUG: #101309【控制面板】【更新】更新页面图标和检查更新时的动画丢失
|
||||
#89824【更新升级-需求-9002】【系统更新】单个待更新包选择全部更新,拒绝安装后不应该提示"部分更新失败";且更新失败后应该出现检测更新的按钮
|
||||
#100839【控制面板|更新】最大字号,一个账户系统语言为英文,一个为中文,英文账户的控制面板-更新界面显示不全
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 无
|
||||
* 其他改动影响域:系统更新插件
|
||||
|
||||
-- luoxueyi <luoxueyi@kylinos.cn> Fri, 24 Dec 2021 10:36:19 +0800
|
||||
|
||||
kylin-system-updater (1.4.0kord) v101; urgency=medium
|
||||
|
||||
* BUG: #99496【系统更新】【英文】【UI布局】更新界面提示信息较长时,页面格式变成左右拖动框与其他界面格式不符
|
||||
#98774【用例104332】【升级】更新历史窗口,左侧名称显示不全
|
||||
#97888【离线更新】【PTOF】控制面板识别不到光盘源中的包
|
||||
#97116【控制面板|更新】更新界面检测按钮显示不全
|
||||
#95290【系统更新】系统语言为英文时,打开控制面板-更新升级页面,再切换到字体页面,将字号切换到15号,返回升级页面,details显示不全
|
||||
#94804【更新升级-需求-9002】【系统更新】应用后的更新按钮内“更新”字样未居中
|
||||
#93555【系统更新】【SP2 UI走查】更新-页面未按最新设计稿实现
|
||||
#85618【内测】【摸底测试】【更新升级】上次更新提示词错误
|
||||
#85312【内测】【摸底测试】【更新升级】更新失败提示字不合理
|
||||
#85269【内测】【控制面板|更新】英文模式下检查更新文字显示不全
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 修改frame边际,保证在显示器不同缩放情况下仍然能够正常显示
|
||||
* 其他改动影响域:系统更新插件
|
||||
|
||||
-- hechengyuan <hechengyuan@kylinos.cn> Fri, 24 Dec 2021 10:36:19 +0800
|
||||
|
||||
kylin-system-updater (1.3.5kord) v101; urgency=medium
|
||||
|
||||
* BUG: #100356【试用模式】点击设置的更新,控制面板闪退(安装完系统后打开不会闪退)
|
||||
#93390 【控制面板|更新】打开控制面板切换深色主题,不关闭控制面板的前提下更新部分文字未反白
|
||||
#91169 【更新升级-需求-9002】【系统更新】开启通知可更新应用后不弹窗通知可更新
|
||||
#99894 【安装器】安装失败-不满足依赖的提示未汉化
|
||||
#97120 【控制面板|更新】软件源更新失败提示语未汉化
|
||||
#99500 【系统更新】【英文】【UI布局】更新界面,update settings与下方标题未对齐
|
||||
#99498 【系统更新】【英文】【UI布局】更新界面,自动更新的第二行介绍显示不全
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 修改部分英文表述和中文翻译
|
||||
* 其他改动影响域:系统更新插件
|
||||
|
||||
-- hechengyuan <hechengyuan@kylinos.cn> Fri, 24 Dec 2021 10:36:19 +0800
|
||||
|
||||
kylin-system-updater (1.3.4kord) v101; urgency=medium
|
||||
|
||||
* BUG: #100356【试用模式】点击设置的更新,控制面板闪退(安装完系统后打开不会闪退)
|
||||
#93390 【控制面板|更新】打开控制面板切换深色主题,不关闭控制面板的前提下更新部分文字未反白
|
||||
#91169 【更新升级-需求-9002】【系统更新】开启通知可更新应用后不弹窗通知可更新
|
||||
#99894 【安装器】安装失败-不满足依赖的提示未汉化
|
||||
#97120 【控制面板|更新】软件源更新失败提示语未汉化
|
||||
#99500 【系统更新】【英文】【UI布局】更新界面,update settings与下方标题未对齐
|
||||
#99498 【系统更新】【英文】【UI布局】更新界面,自动更新的第二行介绍显示不全
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 无
|
||||
* 其他改动影响域:系统更新插件
|
||||
|
||||
-- hechengyuan <hechengyuan@kylinos.cn> Fri, 24 Dec 2021 10:36:19 +0800
|
||||
|
||||
kylin-system-updater (1.3.2.1kord) v101; urgency=medium
|
||||
|
||||
* BUG: 无
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 增加运行依赖python3-distro-info
|
||||
* 其他改动影响域:系统更新插件
|
||||
|
||||
-- luoxueyi <luoxueyi@kylinos.cn> Fri, 24 Dec 2021 10:36:19 +0800
|
||||
|
||||
kylin-system-updater (1.3.2kord) v101; urgency=medium
|
||||
|
||||
* BUG: 无
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 修改与旧版本控制面板的冲突
|
||||
* 其他改动影响域:系统更新插件
|
||||
|
||||
-- luoxueyi <luoxueyi@kylinos.cn> Thu, 23 Dec 2021 16:44:11 +0800
|
||||
|
||||
kylin-system-updater (1.3.1kord) v101; urgency=medium
|
||||
|
||||
* BUG: 无
|
||||
* 需求号: 无
|
||||
* 其他改动说明: 修复点击全部升级后执行更新检测的问题
|
||||
* 其他改动影响域:系统更新全部升级
|
||||
|
||||
-- luoxueyi <luoxueyi@kylinos.cn> Tue, 21 Dec 2021 17:07:57 +0800
|
||||
|
||||
kylin-system-updater (1.3.0kord) v101; urgency=medium
|
||||
|
|
|
@ -71,6 +71,7 @@ Depends: ${python3:Depends},
|
|||
python3-gi (>= 3.8),
|
||||
python3-yaml,
|
||||
aptdaemon,
|
||||
python3-distro-info,
|
||||
ukui-control-center (>= 3.1.1+1103)
|
||||
gettext
|
||||
Breaks:
|
||||
|
|
|
@ -3,6 +3,8 @@ backend/data/kylin-system-updater.db /usr/share/kylin-system-updater/
|
|||
backend/data/30kylin-system-updater /etc/apt/apt.conf.d/
|
||||
backend/data/com.kylin.systemupgrade.conf /etc/dbus-1/system.d/
|
||||
backend/data/kylin-system-updater.service /usr/lib/systemd/system/
|
||||
backend/data/kylin-logout-required /usr/share/kylin-system-updater/
|
||||
backend/data/kylin-reboot-required /usr/share/kylin-system-updater/
|
||||
backend/kylin-system-updater /usr/share/kylin-system-updater/
|
||||
backend/SystemUpdater/*.py /usr/share/kylin-system-updater/SystemUpdater/
|
||||
backend/SystemUpdater/backend/*.py /usr/share/kylin-system-updater/SystemUpdater/backend/
|
||||
|
@ -23,8 +25,9 @@ unattended-upgrades/*.timer /lib/systemd/system/
|
|||
unattended-upgrades/unattended-upgrades-daily /usr/bin/
|
||||
unattended-upgrades/notify /usr/bin/
|
||||
unattended-upgrades/*.desktop /etc/xdg/autostart/
|
||||
unattended-upgrades/unattended-upgrade /usr/bin
|
||||
unattended-upgrades/unattended-upgrade-shutdown /usr/bin
|
||||
unattended-upgrades/kylin-unattended-upgrade /usr/bin
|
||||
unattended-upgrades/kylin-unattended-upgrade-shutdown /usr/bin
|
||||
unattended-upgrades/unattended-upgrades-daily /usr/bin
|
||||
unattended-upgrades/50unattended-upgrades /etc/apt/apt.conf.d/
|
||||
unattended-upgrades/kylin-unattended-upgrades /etc/apt/apt.conf.d/
|
||||
unattended-upgrades/logrotate.d/* /etc/logrotate.d/
|
||||
unattended-upgrades/kylin-unattended-upgrades-logind-maxdelay.conf /usr/lib/systemd/logind.conf.d/
|
||||
|
|
|
@ -17,7 +17,8 @@ fi
|
|||
|
||||
mkdir -p /var/lib/unattended-upgrades
|
||||
chmod +x /usr/bin/unattended-upgrades-daily
|
||||
chmod +x /usr/bin/unattended-upgrade
|
||||
chmod +x /usr/bin/kylin-unattended-upgrade
|
||||
chmod +x /usr/bin/kylin-unattended-upgrade-shutdown
|
||||
systemctl enable unattended-upgrades-download.timer
|
||||
systemctl enable unattended-upgrades-install.timer
|
||||
systemctl enable unattended-upgrades.service
|
||||
systemctl enable kylin-unattended-upgrades.service
|
||||
|
|
|
@ -4,4 +4,4 @@ kylin-update-desktop-kernel-3a4000
|
|||
kylin-update-desktop-ukui
|
||||
kylin-update-desktop-support
|
||||
linux-meta
|
||||
|
||||
kylin-update-desktop-system
|
||||
|
|
148
unattended-upgrades/unattended-upgrade → unattended-upgrades/kylin-unattended-upgrade
Executable file → Normal file
148
unattended-upgrades/unattended-upgrade → unattended-upgrades/kylin-unattended-upgrade
Executable file → Normal file
|
@ -92,6 +92,9 @@ import fcntl
|
|||
import time
|
||||
import subprocess
|
||||
|
||||
SYSTEM_UPDATER_CORE_LIB_PATH="/usr/share/kylin-system-updater/SystemUpdater/Core"
|
||||
sys.path.append(SYSTEM_UPDATER_CORE_LIB_PATH)
|
||||
from OriginFilter import UnattendUpgradeFilter
|
||||
CONFIG_FILE_ROOT_PATH="/var/lib/unattended-upgrades"
|
||||
UNATTENDED_UPGRADE_CONFIG_FILE_PATH="/var/lib/unattended-upgrades/unattended-upgrade.conf"
|
||||
WHITE_LIST_FILE_PATH="/var/lib/kylin-system-updater/system-updater.conf"
|
||||
|
@ -185,6 +188,12 @@ def unLockedEnableShutdown():
|
|||
pidfile = None
|
||||
return False
|
||||
|
||||
def get_white_list_with_version(srclist,list,namelist):
|
||||
for name_with_version in srclist:
|
||||
nvlist = name_with_version.split("=")
|
||||
list.append(nvlist)
|
||||
namelist.append(nvlist[0])
|
||||
|
||||
#global timeStamp
|
||||
|
||||
def get_timestamp():
|
||||
|
@ -364,6 +373,9 @@ class KylinSystemUpdater:
|
|||
ret = self.update_interface.UnattendedUpgradeValue('get','')
|
||||
return ret[0]
|
||||
|
||||
def CheckRebootRequired(self,msg):
|
||||
ret = self.update_interface.CheckRebootRequired(msg)
|
||||
|
||||
def ConnectToSignals(self):
|
||||
def update_detect_finished_handler(success,updatelist,error_status,error_cause):
|
||||
if success:
|
||||
|
@ -457,7 +469,7 @@ PkgFilePin = namedtuple('PkgFilePin', ['id', 'priority'])
|
|||
|
||||
class UnattendedUpgradesCache(apt.Cache):
|
||||
|
||||
def __init__(self, rootdir, whitelist):
|
||||
def __init__(self, rootdir, whitelist,blacklist):
|
||||
|
||||
self._cached_candidate_pkgnames = set() # type: Set[str]
|
||||
|
||||
|
@ -465,15 +477,25 @@ class UnattendedUpgradesCache(apt.Cache):
|
|||
logging.info(_("Allowed origins are: %s"),
|
||||
", ".join(self.allowed_origins))
|
||||
|
||||
self.blacklist = apt_pkg.config.value_list(
|
||||
self.blacklist = blacklist
|
||||
'''
|
||||
apt_pkg.config.value_list(
|
||||
"Unattended-Upgrade::Package-Blacklist")
|
||||
'''
|
||||
logging.info(_("Initial blacklist: %s"), " ".join(self.blacklist))
|
||||
|
||||
self.whitelist = whitelist
|
||||
self.whitelist_with_version = whitelist
|
||||
self.whitelist = []
|
||||
self.get_white_list()
|
||||
# self.whitelist_with_version = []
|
||||
# self.get_white_list_with_version()
|
||||
# self.whitelist = apt_pkg.config.value_list(
|
||||
# "Unattended-Upgrade::Package-Whitelist")
|
||||
self.strict_whitelist = apt_pkg.config.find_b(
|
||||
self.strict_whitelist = False
|
||||
'''
|
||||
apt_pkg.config.find_b(
|
||||
"Unattended-Upgrade::Package-Whitelist-Strict", False)
|
||||
'''
|
||||
logging.info(_("Initial whitelist (%s): %s"),
|
||||
"strict" if self.strict_whitelist else "not strict",
|
||||
" ".join(self.whitelist))
|
||||
|
@ -494,6 +516,10 @@ class UnattendedUpgradesCache(apt.Cache):
|
|||
logging.debug("Using %s regexp to find running kernel packages",
|
||||
self.running_kernel_pkgs_regexp.pattern)
|
||||
|
||||
def get_white_list(self):
|
||||
for name_with_version in self.whitelist_with_version:
|
||||
self.whitelist.append(name_with_version[0])
|
||||
|
||||
def find_better_version(self, pkg):
|
||||
# type (apt.Package) -> apt.package.Version
|
||||
if pkg.is_installed and pkg.versions[0] > pkg.installed:
|
||||
|
@ -699,8 +725,12 @@ class UnattendedUpgradesCache(apt.Cache):
|
|||
return
|
||||
else:
|
||||
function = apt.package.Package.mark_install
|
||||
|
||||
marking_succeeded = self.call_checked(function, pkg, **kwargs)
|
||||
|
||||
if not marking_succeeded:
|
||||
logging.error("%s mark failed"%pkg.name)
|
||||
|
||||
if (not marking_succeeded
|
||||
or not check_changes_for_sanity(self, desired_pkg=pkg)) \
|
||||
and allow_marking_fallback():
|
||||
|
@ -719,7 +749,7 @@ class UnattendedUpgradesCache(apt.Cache):
|
|||
pass
|
||||
|
||||
self.call_checked(function, pkg, **kwargs)
|
||||
|
||||
|
||||
for marked_pkg in self.get_changes():
|
||||
if marked_pkg.name in self._cached_candidate_pkgnames:
|
||||
continue
|
||||
|
@ -745,7 +775,7 @@ class UnattendedUpgradesCache(apt.Cache):
|
|||
new_pkg_adjusted = True
|
||||
if new_pkg_adjusted:
|
||||
self.call_adjusted(function, pkg, **kwargs)
|
||||
|
||||
|
||||
def mark_upgrade_adjusted(self, pkg, **kwargs):
|
||||
self.call_adjusted(apt.package.Package.mark_upgrade, pkg, **kwargs)
|
||||
|
||||
|
@ -1107,10 +1137,13 @@ def get_allowed_origins_legacy():
|
|||
|
||||
def get_allowed_origins():
|
||||
# type: () -> List[str]
|
||||
uuf = UnattendUpgradeFilter()
|
||||
allowed_origins = uuf.GetAllowOrigins()
|
||||
""" return a list of allowed origins from apt.conf
|
||||
|
||||
This will take substitutions (like distro_id) into account.
|
||||
"""
|
||||
'''
|
||||
allowed_origins = get_allowed_origins_legacy()
|
||||
key = "Unattended-Upgrade::Origins-Pattern"
|
||||
try:
|
||||
|
@ -1119,6 +1152,8 @@ def get_allowed_origins():
|
|||
except ValueError:
|
||||
logging.error(_("Unable to parse %s." % key))
|
||||
raise
|
||||
'''
|
||||
#logging.info("allowed origins are:%s"%"\n".join(allowed_origins))
|
||||
return allowed_origins
|
||||
|
||||
|
||||
|
@ -1158,6 +1193,8 @@ def match_whitelist_string(whitelist, origin):
|
|||
match = fnmatch.fnmatch(origin.site, value)
|
||||
elif what in ("n", "codename",):
|
||||
match = fnmatch.fnmatch(origin.codename, value)
|
||||
elif what in ("uri"):
|
||||
pass
|
||||
else:
|
||||
raise UnknownMatcherError(
|
||||
"Unknown whitelist entry for matcher %s (token %s)" % (
|
||||
|
@ -1317,7 +1354,7 @@ def is_in_allowed_origin(ver, allowed_origins):
|
|||
def ver_in_allowed_origin(pkg, allowed_origins):
|
||||
# type: (apt.Package, List[str]) -> apt.package.Version
|
||||
for ver in pkg.versions:
|
||||
if is_in_allowed_origin(ver, allowed_origins):
|
||||
if is_in_allowed_origin(ver, allowed_origins):
|
||||
# leave as soon as we have the highest new candidate
|
||||
return ver
|
||||
raise NoAllowedOriginError()
|
||||
|
@ -1354,12 +1391,14 @@ def is_pkg_change_allowed(pkg, blacklist, whitelist, strict_whitelist):
|
|||
# whitelist, most people will want the relaxed whitelist
|
||||
# that whitelists a package but pulls in the package
|
||||
# dependencies
|
||||
|
||||
if strict_whitelist and \
|
||||
not is_pkgname_in_whitelist(pkg.name, whitelist):
|
||||
|
||||
logging.debug("pkg %s package is not whitelisted" %
|
||||
pkg.name)
|
||||
return False
|
||||
|
||||
if pkg._pkg.selected_state == apt_pkg.SELSTATE_HOLD:
|
||||
logging.debug("pkg %s is on hold" % pkg.name)
|
||||
return False
|
||||
|
@ -1416,8 +1455,8 @@ def check_changes_for_sanity(cache, desired_pkg=None):
|
|||
if sanity_check_result is None:
|
||||
return True
|
||||
else:
|
||||
logging.debug("sanity check failed for: %s : %s"
|
||||
% (str({str(p.candidate) for p in cache.get_changes()}),
|
||||
logging.debug("sanity check failed for: %s:%s : %s"
|
||||
% (desired_pkg.name,str({str(p.candidate) for p in cache.get_changes()}),
|
||||
sanity_check_result))
|
||||
return False
|
||||
|
||||
|
@ -1429,17 +1468,22 @@ def sanity_problem(cache, desired_pkg):
|
|||
# If there are no packages to be installed they were kept back
|
||||
if cache.install_count == 0:
|
||||
return ("no package is selected to be upgraded or installed")
|
||||
|
||||
changes = cache.get_changes()
|
||||
|
||||
for pkg in changes:
|
||||
if pkg.marked_delete:
|
||||
return ("pkg %s is marked to be deleted" % pkg.name)
|
||||
|
||||
if pkg.marked_install or pkg.marked_upgrade:
|
||||
# apt will never fallback from a trusted to a untrusted
|
||||
# origin so its good enough if we have a single trusted one
|
||||
|
||||
if not any([o.trusted for o in pkg.candidate.origins]):
|
||||
return ("pkg %s is not from a trusted origin" % pkg.name)
|
||||
if not is_in_allowed_origin(pkg.candidate, cache.allowed_origins):
|
||||
return ("pkg %s is not in an allowed origin" % pkg.name)
|
||||
|
||||
if not is_pkg_change_allowed(pkg,
|
||||
cache.blacklist,
|
||||
cache.whitelist,
|
||||
|
@ -1447,13 +1491,16 @@ def sanity_problem(cache, desired_pkg):
|
|||
return ("pkg %s is blacklisted or is not whitelisted"
|
||||
% pkg.name)
|
||||
# check if the package is unsafe to upgrade unattended
|
||||
'''
|
||||
ignore_require_restart = apt_pkg.config.find_b(
|
||||
"Unattended-Upgrade::IgnoreAppsRequireRestart", False)
|
||||
upgrade_requires = pkg.candidate.record.get("Upgrade-Requires")
|
||||
|
||||
if pkg.marked_upgrade and ignore_require_restart is False \
|
||||
and upgrade_requires == "app-restart":
|
||||
return ("pkg %s requires app-restart, it is not safe to "
|
||||
"upgrade it unattended")
|
||||
'''
|
||||
# check that the package we want to upgrade is in the change set
|
||||
if desired_pkg and desired_pkg not in changes:
|
||||
return ("pkg %s to be marked for upgrade/install is not marked "
|
||||
|
@ -2022,17 +2069,24 @@ def try_to_upgrade(pkg, # type: apt.Package
|
|||
):
|
||||
# type: (...) -> None
|
||||
try:
|
||||
|
||||
try:
|
||||
# try to adjust pkg itself first, if that throws an exception it
|
||||
# can't be upgraded on its own
|
||||
cache.adjust_candidate(pkg)
|
||||
'''
|
||||
if not pkg.is_upgradable and not apt_pkg.config.find_b(
|
||||
"Unattended-Upgrade::Allow-downgrade", False):
|
||||
return
|
||||
return
|
||||
'''
|
||||
except NoAllowedOriginError:
|
||||
return
|
||||
|
||||
cache._cached_candidate_pkgnames.add(pkg.name)
|
||||
cache.mark_upgrade_adjusted(pkg, from_user=not pkg.is_auto_installed)
|
||||
if not pkg.installed:
|
||||
cache.mark_install_adjusted(pkg,from_user=True)
|
||||
else:
|
||||
cache.mark_upgrade_adjusted(pkg, from_user=not pkg.is_auto_installed)
|
||||
if check_changes_for_sanity(cache, pkg):
|
||||
# add to packages to upgrade
|
||||
pkgs_to_upgrade.append(pkg)
|
||||
|
@ -2056,29 +2110,41 @@ def candidate_version_changed(pkg, # type: apt.Package
|
|||
|
||||
def calculate_upgradable_pkgs(cache, # type: UnattendedUpgradesCache
|
||||
options, # type: Options
|
||||
):
|
||||
whitelist):
|
||||
# type: (...) -> List[apt.Package]
|
||||
pkgs_to_upgrade = [] # type: List[apt.Package]
|
||||
|
||||
# now do the actual upgrade
|
||||
for pkg in cache:
|
||||
for pkgname in whitelist:
|
||||
try:
|
||||
pkg = cache[pkgname]
|
||||
except Exception as e:
|
||||
logging.error("error checking pkg:%s"%e)
|
||||
continue
|
||||
#for pkg in cache:
|
||||
# if pkg.name not in cache.whitelist:
|
||||
# logging.debug("%s not in whitelist skipping..."%(pkg.name))
|
||||
# continue
|
||||
|
||||
if options.debug and pkg.is_upgradable \
|
||||
or candidate_version_changed(pkg):
|
||||
logging.debug("Checking: %s (%s)" % (
|
||||
pkg.name, getattr(pkg.candidate, "origins", [])))
|
||||
|
||||
if (pkg.is_upgradable or candidate_version_changed(pkg)):#is_pkgname_in_whitelist(pkg.name, cache.whitelist)):
|
||||
|
||||
if (pkg.is_upgradable or candidate_version_changed(pkg) or not pkg.is_installed):#is_pkgname_in_whitelist(pkg.name, cache.whitelist)):
|
||||
|
||||
try:
|
||||
ver_in_allowed_origin(pkg, cache.allowed_origins)
|
||||
except NoAllowedOriginError:
|
||||
continue
|
||||
|
||||
try_to_upgrade(pkg,
|
||||
pkgs_to_upgrade,
|
||||
cache)
|
||||
|
||||
|
||||
logging.debug("Checking: %s (%s)" % (
|
||||
pkg.name, getattr(pkg.candidate, "origins", [])))
|
||||
#pkgs_to_upgrade.append(pkg)
|
||||
if cache.get_changes():
|
||||
cache.clear()
|
||||
|
||||
|
@ -2308,11 +2374,11 @@ def main(options, rootdir="/"):
|
|||
pass
|
||||
|
||||
# lock for the shutdown check
|
||||
shutdown_lock = apt_pkg.get_lock(LOCK_FILE)
|
||||
if shutdown_lock < 0:
|
||||
logging.error("Lock file is already taken, exiting")
|
||||
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle")
|
||||
return 1
|
||||
# shutdown_lock = apt_pkg.get_lock(LOCK_FILE)
|
||||
# if shutdown_lock < 0:
|
||||
# logging.error("Lock file is already taken, exiting")
|
||||
# WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle")
|
||||
# return 1
|
||||
|
||||
try:
|
||||
res = run(options, rootdir, mem_log, logfile_dpkg,
|
||||
|
@ -2327,10 +2393,12 @@ def main(options, rootdir="/"):
|
|||
# there is some meaningful result which is worth an email
|
||||
log_content = get_dpkg_log_content(logfile_dpkg,
|
||||
install_start_time)
|
||||
'''
|
||||
send_summary_mail(res.pkgs, res.success, res.result_str,
|
||||
res.pkgs_kept_back, res.pkgs_removed,
|
||||
res.pkgs_kept_installed, mem_log,
|
||||
log_content)
|
||||
'''
|
||||
if res.update_stamp:
|
||||
# write timestamp file
|
||||
write_stamp_file()
|
||||
|
@ -2369,8 +2437,15 @@ def mark_pkgs_to_upgrade(cache, pkgs_to_upgrade):
|
|||
cache.mark_upgrade_adjusted(pkg,
|
||||
from_user=not pkg.is_auto_installed)
|
||||
elif not pkg.is_installed:
|
||||
cache.mark_install_adjusted(pkg, from_user=False)
|
||||
cache.mark_install_adjusted(pkg, from_user=True)
|
||||
|
||||
def adjust_candidate_with_version(cache,pkgnamelist,versionlist):
|
||||
for pkgname in pkgnamelist:
|
||||
pkg = cache[pkgname]
|
||||
for v in pkg.versions:
|
||||
if is_in_allowed_origin(v,cache.allowed_origins):
|
||||
if str(v) in versionlist:
|
||||
pkg.candidate = v
|
||||
|
||||
def run(options, # type: Options
|
||||
rootdir, # type: str
|
||||
|
@ -2389,6 +2464,7 @@ def run(options, # type: Options
|
|||
return UnattendedUpgradesResult(False)
|
||||
|
||||
# check to see if want to auto-upgrade the devel release
|
||||
'''
|
||||
if apt_pkg.config.find("Unattended-Upgrade::DevRelease") == "auto":
|
||||
try:
|
||||
if DISTRO_ID.lower() == 'ubuntu':
|
||||
|
@ -2422,7 +2498,7 @@ def run(options, # type: Options
|
|||
syslog.syslog(_("Not running on the development release."))
|
||||
logging.info(_("Not running on the development release."))
|
||||
return UnattendedUpgradesResult(True)
|
||||
|
||||
'''
|
||||
logging.info(_("Starting unattended upgrades script"))
|
||||
kylin_system_updater = KylinSystemUpdater()
|
||||
if KylinSystemUpdater.GetUnattendedUpgradeValue:
|
||||
|
@ -2465,10 +2541,16 @@ def run(options, # type: Options
|
|||
|
||||
config_manager = ConfigFileManager(CONFIG_FILE_ROOT_PATH)
|
||||
white_list = config_manager.ReadListFromFile(WHITE_LIST_FILE_PATH,'AutoUpgrade','upgradelist')
|
||||
global wl
|
||||
wl = white_list
|
||||
logging.debug("white list from kylin system updater:%s"%("\n".join(white_list)))
|
||||
white_list_with_version =[]
|
||||
namelist = []
|
||||
blacklist = []
|
||||
get_white_list_with_version(white_list,white_list_with_version,namelist)
|
||||
# get a cache
|
||||
try:
|
||||
cache = UnattendedUpgradesCache(rootdir=rootdir,whitelist=white_list)
|
||||
cache = UnattendedUpgradesCache(rootdir=rootdir,whitelist=white_list_with_version,blacklist=blacklist)
|
||||
#cache.whitelist=white_list
|
||||
except SystemError as error:
|
||||
print(_("Apt returned an error, exiting"))
|
||||
|
@ -2500,16 +2582,17 @@ def run(options, # type: Options
|
|||
auto_removable = get_auto_removable(cache)
|
||||
|
||||
# find out about the packages that are upgradable (in an allowed_origin)
|
||||
pkgs_to_upgrade = calculate_upgradable_pkgs(cache, options)
|
||||
pkgs_to_upgrade = calculate_upgradable_pkgs(cache, options,namelist)
|
||||
pkgs_to_upgrade.sort(key=lambda p: p.name)
|
||||
pkgs = [pkg.name for pkg in pkgs_to_upgrade]
|
||||
logging.debug("pkgs that look like they should be upgraded: %s"
|
||||
logging.debug("pkgs that look like they should be upgraded or installed: %s"
|
||||
% "\n".join(pkgs))
|
||||
|
||||
# FIXME: make this into a ContextManager
|
||||
# stop being nice
|
||||
os.nice(old_priority - os.nice(0))
|
||||
|
||||
adjust_candidate_with_version(cache,namelist,white_list)
|
||||
# download what looks good
|
||||
mark_pkgs_to_upgrade(cache, pkgs)
|
||||
|
||||
|
@ -2812,6 +2895,8 @@ def run(options, # type: Options
|
|||
logfile_dpkg)
|
||||
unLockedEnableShutdown()
|
||||
subprocess.Popen('dbus-send --system --type=signal / com.kylin.install.notification.InstallFinish',shell=True)
|
||||
if pkg_install_success:
|
||||
kylin_system_updater.CheckRebootRequired("unattended-upgrades")
|
||||
# Was the overall run succesful: only if everything installed
|
||||
# fine and nothing was held back because of a conffile prompt.
|
||||
successful_run = (kernel_pkgs_remove_success and pkg_install_success
|
||||
|
@ -2848,7 +2933,7 @@ def run(options, # type: Options
|
|||
successful_run = successful_run and pkg_remove_success
|
||||
# the user wants *only new* auto-removals to be removed
|
||||
elif apt_pkg.config.find_b(
|
||||
"Unattended-Upgrade::Remove-New-Unused-Dependencies", True):
|
||||
"Unattended-Upgrade::Remove-New-Unused-Dependencies", False):
|
||||
# calculate the new auto-removals
|
||||
new_pending_autoremovals = get_auto_removable(cache)
|
||||
auto_removals = new_pending_autoremovals - previous_autoremovals
|
||||
|
@ -2891,9 +2976,16 @@ class Options:
|
|||
self.verbose = False
|
||||
self.minimal_upgrade_steps = False
|
||||
|
||||
shutdown_lock = -1
|
||||
|
||||
if __name__ == "__main__":
|
||||
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle")
|
||||
# lock for the shutdown check
|
||||
shutdown_lock = apt_pkg.get_lock(LOCK_FILE)
|
||||
if shutdown_lock < 0:
|
||||
logging.error("Lock file is already taken, exiting")
|
||||
#WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle")
|
||||
sys.exit(0)
|
||||
localesApp = "unattended-upgrades"
|
||||
localesDir = "/usr/share/locale"
|
||||
gettext.bindtextdomain(localesApp, localesDir)
|
||||
|
@ -2958,7 +3050,7 @@ if __name__ == "__main__":
|
|||
signal.signal(signal.SIGHUP, signal.SIG_IGN)
|
||||
|
||||
# setup signal handler for graceful stopping
|
||||
signal.signal(signal.SIGTERM, signal_handler_term)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
|
||||
signal.signal(signal.SIGINT,signal_handler_int)
|
||||
|
|
@ -325,7 +325,7 @@ class UnattendedUpgradesShutdown():
|
|||
env["UNATTENDED_UPGRADES_FORCE_INSTALL_ON_SHUTDOWN"] = "1"
|
||||
logging.debug("starting unattended-upgrades in shutdown mode")
|
||||
self.on_shutdown_mode_uu_proc = subprocess.Popen(
|
||||
["unattended-upgrade","--install-only"], env=env)
|
||||
["kylin-unattended-upgrade","--install-only"], env=env)
|
||||
log_msg(_("Running unattended-upgrades in shutdown mode"))
|
||||
# run u-u, but switch to stopping when receiving stop signal
|
||||
# because it means shutdown progressed despite holding the lock
|
|
@ -0,0 +1,3 @@
|
|||
[Login]
|
||||
# delay
|
||||
InhibitDelayMaxSec=1800
|
|
@ -5,7 +5,7 @@ RequiresMountsFor=/run /var/log /var/run /var/lib /boot
|
|||
Documentation=man:unattended-upgrade(8)
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/unattended-upgrade-shutdown --wait-for-signal
|
||||
ExecStart=/usr/bin/kylin-unattended-upgrade-shutdown --wait-for-signal
|
||||
KillMode=process
|
||||
TimeoutStopSec=1800
|
||||
|
|
@ -114,8 +114,8 @@ if [ "$1" = "download" ] || [ -z "$1" ] ; then
|
|||
|
||||
# download all upgradeable packages (if it is requested)
|
||||
DOWNLOAD_STAMP=/var/lib/apt/periodic/kylin-auto-download-stamp
|
||||
if which unattended-upgrade >/dev/null 2>&1 && check_stamp $DOWNLOAD_STAMP $KylinAutodownloadInterval; then
|
||||
if unattended-upgrade --download-only; then
|
||||
if which kylin-unattended-upgrade >/dev/null 2>&1 && check_stamp $DOWNLOAD_STAMP $KylinAutodownloadInterval; then
|
||||
if kylin-unattended-upgrade --download-only; then
|
||||
update_stamp $DOWNLOAD_STAMP
|
||||
debug_echo "kylin-autoupdate-download (success)"
|
||||
else
|
||||
|
@ -129,8 +129,8 @@ fi
|
|||
if [ "$1" = "install" ] || [ -z "$1" ] ; then
|
||||
# auto upgrade all upgradeable packages
|
||||
INSTALL_STAMP=/var/lib/apt/periodic/kylin-auto-install-stamp
|
||||
if which unattended-upgrade >/dev/null 2>&1 && check_stamp $INSTALL_STAMP $KylinAutoInstallInterval; then
|
||||
if unattended-upgrade --install-only; then
|
||||
if which kylin-unattended-upgrade >/dev/null 2>&1 && check_stamp $INSTALL_STAMP $KylinAutoInstallInterval; then
|
||||
if kylin-unattended-upgrade --install-only; then
|
||||
update_stamp $INSTALL_STAMP
|
||||
debug_echo "kylin-autoupdate-install (success)"
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue