同步主线变动

This commit is contained in:
wangsong 2023-05-29 14:47:39 +08:00
parent 192a914ee6
commit 7c74313253
31 changed files with 3089 additions and 1339 deletions

View File

@ -16,6 +16,7 @@ import tarfile
import requests import requests
import datetime import datetime
import threading import threading
import subprocess
from email import message from email import message
from datetime import datetime from datetime import datetime
@ -32,6 +33,7 @@ from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
LOCALTIDDIR = "/var/lib/kylin-system-updater/" LOCALTIDDIR = "/var/lib/kylin-system-updater/"
LOCALTIDFILE = "tidfile.conf" LOCALTIDFILE = "tidfile.conf"
MSGSNDDIR = "/var/lib/kylin-system-updater/sendinfos/" MSGSNDDIR = "/var/lib/kylin-system-updater/sendinfos/"
SERVERID = "/var/lib/kylin-software-properties/config/serverID.conf"
SOURCE_PKGNAME = { SOURCE_PKGNAME = {
'Kylin System Updater': 'kylin-system-updater', 'Kylin System Updater': 'kylin-system-updater',
@ -126,6 +128,17 @@ class UpdateMsgCollector():
UploadMessage['UUID'] = str(local_uuid) UploadMessage['UUID'] = str(local_uuid)
else: else:
UploadMessage['UUID'] = str(uuid.uuid1()) UploadMessage['UUID'] = str(uuid.uuid1())
serverid_configs = UpgradeConfig(datadir = "/var/lib/kylin-software-properties/config/", name = "serverID.conf")
tans_id = serverid_configs.getWithDefault("ID", "pushID", " ")
UploadMessage['transactionID'] = tans_id
snobj = dbus.SystemBus().get_object('org.freedesktop.activation', '/org/freedesktop/activation')
sninterface = dbus.Interface(snobj, dbus_interface='org.freedesktop.activation.interface')
retval,retid = sninterface.serial_number()
if(retid==0):
UploadMessage['serialNumber'] = str(retval)
else:
UploadMessage['serialNumber'] = ''
except Exception as e: except Exception as e:
logging.error(str(e)) logging.error(str(e))
@ -186,7 +199,6 @@ class UpdateMsgCollector():
try: try:
self.upgrade_list = upgrade_list self.upgrade_list = upgrade_list
self.upgrade_mode = mode self.upgrade_mode = mode
self.uuid = str(uuid.uuid1())
self.UpdateInfos.update({"upgradeMode":self.mode_map.get(self.upgrade_mode, "default-mode")}) self.UpdateInfos.update({"upgradeMode":self.mode_map.get(self.upgrade_mode, "default-mode")})
except DBusException as e: except DBusException as e:
logging.error(e) logging.error(e)
@ -196,6 +208,11 @@ class UpdateMsgCollector():
tmp_dict = {} tmp_dict = {}
tmp_dict.update(dict_msg) tmp_dict.update(dict_msg)
try: try:
self.Init_UUID()
if 'error_string' in tmp_dict.keys() and 'error_desc' in tmp_dict.keys():
if tmp_dict['error_string'] == "下载失败" and tmp_dict['error_desc'] == "取消升级":
tmp_dict.update({"error_string":str(tmp_dict['error_string']+","+tmp_dict['error_desc'])})
tmp_dict.update({"error_desc":str(tmp_dict['error_string']+","+tmp_dict['error_desc'])})
self.UpdateInfos.update({"step":self.action_map.get(action, "")}) self.UpdateInfos.update({"step":self.action_map.get(action, "")})
if self.upgrade_mode == self.MODE_INSTALL_SYSTEM: if self.upgrade_mode == self.MODE_INSTALL_SYSTEM:
self.UpdateInfos.update({"appname":"Upgrade System"}) self.UpdateInfos.update({"appname":"Upgrade System"})
@ -222,10 +239,16 @@ class UpdateMsgCollector():
self.background_version.update({pkg.name:"Unknown"}) self.background_version.update({pkg.name:"Unknown"})
self.background_list.append(pkg.name) self.background_list.append(pkg.name)
def Init_UUID(self):
if self.uuid == "":
self.uuid = str(uuid.uuid1())
def Msg_Clean(self): def Msg_Clean(self):
self.UploadMessage = {} self.UploadMessage = {}
self.PackageInfo = {} self.PackageInfo = {}
self.UpdateInfos = {} self.UpdateInfos = {}
self.uuid = ""
class FormatConvert(): class FormatConvert():
def __init__(self, DataCollector): def __init__(self, DataCollector):
#秘钥 #秘钥

View File

@ -315,7 +315,7 @@ def CopyData():
if (_is_first_migration(new_db, new_db_cursor)): if (_is_first_migration(new_db, new_db_cursor)):
# 数据迁移 # 数据迁移
dateMigration(new_db=new_db, new_db_cursor=new_db_cursor) dateMigration(new_db=new_db, new_db_cursor=new_db_cursor)
sql_commnd = "UPDATE display SET firstmigration='no';" sql_commnd = "UPDATE display SET firstmigration='false';"
new_db_cursor.execute(sql_commnd) new_db_cursor.execute(sql_commnd)
new_db.commit() new_db.commit()
else: else:
@ -324,11 +324,11 @@ def CopyData():
# 新增 firstmigration 字段 # 新增 firstmigration 字段
sql_commnd = "alter table display add column firstmigration text;" sql_commnd = "alter table display add column firstmigration text;"
new_db_cursor.execute(sql_commnd) new_db_cursor.execute(sql_commnd)
sql_commnd = "UPDATE display SET firstmigration='yes';" sql_commnd = "UPDATE display SET firstmigration='true';"
new_db_cursor.execute(sql_commnd) new_db_cursor.execute(sql_commnd)
#数据迁移 #数据迁移
dateMigration(new_db=new_db, new_db_cursor=new_db_cursor) dateMigration(new_db=new_db, new_db_cursor=new_db_cursor)
sql_commnd = "UPDATE display SET firstmigration='no';" sql_commnd = "UPDATE display SET firstmigration='false';"
new_db_cursor.execute(sql_commnd) new_db_cursor.execute(sql_commnd)
new_db.commit() new_db.commit()

View File

@ -9,6 +9,7 @@ import shutil
import sqlite3 import sqlite3
import logging import logging
import datetime import datetime
from operator import itemgetter
from gettext import gettext as _ from gettext import gettext as _
from sys import exec_prefix from sys import exec_prefix
from SystemUpdater.Core.DataAcquisition import PHPSeverSend from SystemUpdater.Core.DataAcquisition import PHPSeverSend
@ -20,11 +21,14 @@ from ..backend import InstallBackend
DB_FILE = os.path.join("/var/cache/kylin-system-updater/kylin-system-updater.db") DB_FILE = os.path.join("/var/cache/kylin-system-updater/kylin-system-updater.db")
# UMDB_FILE = os.path.join("/var/cache/kylin-system-updater/kylin-system-updater.db") # UMDB_FILE = os.path.join("/var/cache/kylin-system-updater/kylin-system-updater.db")
DB_UPDATER = "/var/cache/kylin-update-manager/kylin-update-manager.db"
DB_UPGRADE = "/var/cache/kylin-system-updater/kylin-system-updater.db"
VER_DB = "/usr/share/kylin-system-updater/kylin-system-updater.db"
INSTALLED_LIST = [{"item": "errorcode", "type": "int", "default": "0"}] INSTALLED_LIST = [{"item": "errorcode", "type": "int", "default": "0"}]
DISPALY_LIST = [] DISPALY_LIST = []
class Sqlite3Server(object): class Sqlite3Server(object):
def __init__(self, updateManager): def __init__(self, updateManager, _no_DataMigration=False):
self.connect = None self.connect = None
self.window_main = updateManager self.window_main = updateManager
self.config_path = get_config_patch() self.config_path = get_config_patch()
@ -33,8 +37,31 @@ class Sqlite3Server(object):
# uncoverable配置文件 # uncoverable配置文件
self.ucconfigs = UpgradeConfig(datadir = "/etc/kylin-version", name = "kylin-system-version.conf") self.ucconfigs = UpgradeConfig(datadir = "/etc/kylin-version", name = "kylin-system-version.conf")
self._system_version_config() self._system_version_config()
#判断数据迁移
if not _no_DataMigration:
if (not os.path.exists(DB_UPDATER)):
logging.debug("Can not found database: %s, should ignore.",DB_UPDATER)
self.__need_DataMigration(mark_FirstMigration = True)
else:
self.__need_DataMigration(mark_FirstMigration = False)
self.current_purge_pkgs = []
self.init_metadata()
# 初始化连接数据库,修改为使用时连接 def init_metadata(self):
self.deb_metadata = {}
self.deb_metadata.update({"current_install_debfile":""})
self.deb_metadata.update({"absolute_path":""})
self.deb_metadata.update({"debname":""})
self.deb_metadata.update({"deblist":[]})
self.deb_metadata.update({"action":''})
self.deb_metadata.update({"mode":''})
self.deb_metadata.update({"source":''})
self.deb_metadata.update({"sender":''})
self.deb_metadata.update({"caller":''})
self.deb_metadata.update({"old_version":''})
self.deb_metadata.update({"new_version":''})
# Initialize the connection database and modify it to connect when using
def init_sqlit(self): def init_sqlit(self):
try: try:
logging.info(_("Initialize database files ...")) logging.info(_("Initialize database files ..."))
@ -48,7 +75,6 @@ class Sqlite3Server(object):
#connect连接数据库 #connect连接数据库
def connect_database(self): def connect_database(self):
try: try:
logging.debug("Connect database ...")
self.connect = sqlite3.connect(DB_FILE, check_same_thread=False) self.connect = sqlite3.connect(DB_FILE, check_same_thread=False)
self.cursor = self.connect.cursor() self.cursor = self.connect.cursor()
except Exception as e: except Exception as e:
@ -57,10 +83,9 @@ class Sqlite3Server(object):
#disconnect连接数据库 #disconnect连接数据库
def disconnect_database(self): def disconnect_database(self):
try: try:
logging.debug("Disconnect database ...")
if self.connect != None: if self.connect != None:
self.connect.close() self.connect.close()
if self.connect != None: if self.cursor != None:
del self.cursor del self.cursor
except Exception as e: except Exception as e:
logging.error("Failed to disconnect database: %s", str(e)) logging.error("Failed to disconnect database: %s", str(e))
@ -194,12 +219,49 @@ class Sqlite3Server(object):
logging.info(_("Database: Insert To updateinfos Complete...")) logging.info(_("Database: Insert To updateinfos Complete..."))
self.disconnect_database() self.disconnect_database()
#get display data
def gen_display_mate(self)->dict:
mateData = {}
self.connect_database()
try:
sql = "pragma table_info({})".format("display")
self.cursor.execute(sql)
keys=[key[1] for key in self.cursor.fetchall()]
sql = "select * from display where id=1;"
self.cursor.execute(sql)
values = self.cursor.fetchone()
mateData = dict(zip(keys, values))
#
# self.connect.row_factory = self.dictFactory
# values = self.cursor.execute("select * from display where id=1;").fetchall()
except Exception as e:
logging.error("select error: %s.", str(e))
self.disconnect_database()
return mateData
def dictFactory(self,cursor,row):
"""将sql查询结果整理成字典形式"""
d={}
for index,col in enumerate(cursor.description):
d[col[0]]=row[index]
return d
def __need_DataMigration(self, mark_FirstMigration = False):
# mateData = self.gen_display_mate()
# if "firstmigration" in mateData.keys() and mateData["firstmigration"] == "true":
dm = DataMigration()
if (mark_FirstMigration):
dm.MarkFirstMigration()
else:
dm.CopyData()
# 接收更新列表与信息,生成数据并插入数据库中 # 接收更新列表与信息,生成数据并插入数据库中
def insert_info(self, mode, pkg_list=[], pkg_group=[], adjust_pkg=[], success = False, error_string = '', error_desc = ''): def insert_info(self, mode, pkg_list=[], pkg_group=[], adjust_pkg=[], success = False, error_string = '', error_desc = ''):
errstr = error_string + " " + error_desc errstr = error_string + " " + error_desc
status = " " status = " "
status_cn = " " status_cn = " "
appname_cn = "" appname_cn = ""
errorcode = "10000"
UpdateInfos = {} UpdateInfos = {}
InstallInfos = {} InstallInfos = {}
time = datetime.datetime.now() time = datetime.datetime.now()
@ -215,9 +277,11 @@ class Sqlite3Server(object):
if success: if success:
status = 'success' status = 'success'
status_cn = '成功' status_cn = '成功'
errorcode = "10000000"
else: else:
status = 'failed' status = 'failed'
status_cn = '失败' status_cn = '失败'
errorcode = "10000100"
changeLog = "" changeLog = ""
try: try:
@ -233,17 +297,21 @@ class Sqlite3Server(object):
UpdateInfos.update({"appname":str(pkgname)}) UpdateInfos.update({"appname":str(pkgname)})
UpdateInfos.update({"source":"Kylin System Updater"}) UpdateInfos.update({"source":"Kylin System Updater"})
UpdateInfos.update({"status":status}) UpdateInfos.update({"status":status})
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)}) UpdateInfos.update({"errorCode":str(errorcode)})
UpdateInfos.update({"error_string":str(error_string)})
UpdateInfos.update({"error_desc":str(error_desc)})
self.window_main.collector.Upgrade_Process_Msg("finish-update", UpdateInfos.copy()) self.window_main.collector.Upgrade_Process_Msg("finish-update", UpdateInfos.copy())
#安装信息install-infos #安装信息install-infos
InstallInfos.update({"appname":str(pkgname)}) InstallInfos.update({"appname":str(pkgname)})
if pkgname in self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'].keys(): if pkgname in self.window_main.main_meta.versoin_pkgs['groups_upgrade'].keys():
InstallInfos.update({"old_version":str(self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'][pkgname])}) InstallInfos.update({"old_version":str(self.window_main.main_meta.versoin_pkgs['groups_upgrade'][pkgname])})
else: else:
InstallInfos.update({"old_version":'UnKnown'}) InstallInfos.update({"old_version":'UnKnown'})
InstallInfos.update({"new_version":str(pkgversion)}) InstallInfos.update({"new_version":str(pkgversion)})
InstallInfos.update({"status":status}) InstallInfos.update({"status":status})
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)}) InstallInfos.update({"errorCode":str(errorcode)})
InstallInfos.update({"error_string":str(error_string)})
InstallInfos.update({"error_desc":str(error_desc)})
self.window_main.collector.Upgrade_Process_Msg("finish-install", InstallInfos.copy()) self.window_main.collector.Upgrade_Process_Msg("finish-install", InstallInfos.copy())
# 系统升级完成 ..判断版本号 # 系统升级完成 ..判断版本号
if status == "success" and "kylin-update-desktop-system" in pkgname: if status == "success" and "kylin-update-desktop-system" in pkgname:
@ -256,7 +324,7 @@ class Sqlite3Server(object):
self._removal_of_marker() self._removal_of_marker()
#FIXME: 临时方案 PHP #FIXME: 临时方案 PHP
PHPSeverSend(_appname=pkgname, _appversion=pkgversion, _statue=status, _errorcode="10000100", _errorstring=errstr) PHPSeverSend(_appname=pkgname, _appversion=pkgversion, _statue=status, _errorcode=str(errorcode), _errorstring=errstr)
file_path = os.path.join(get_config_patch(), str(pkgname) + ".yaml") file_path = os.path.join(get_config_patch(), str(pkgname) + ".yaml")
with open(file_path, "r") as stream: with open(file_path, "r") as stream:
try: try:
@ -299,22 +367,26 @@ class Sqlite3Server(object):
UpdateInfos.update({"appname":str(pkgname)}) UpdateInfos.update({"appname":str(pkgname)})
UpdateInfos.update({"source":"Kylin System Updater"}) UpdateInfos.update({"source":"Kylin System Updater"})
UpdateInfos.update({"status":status}) UpdateInfos.update({"status":status})
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)}) UpdateInfos.update({"errorCode":str(errorcode)})
UpdateInfos.update({"error_string":str(error_string)})
UpdateInfos.update({"error_desc":str(error_desc)})
self.window_main.collector.Upgrade_Process_Msg("finish-update", UpdateInfos.copy()) self.window_main.collector.Upgrade_Process_Msg("finish-update", UpdateInfos.copy())
#安装信息install-infos #安装信息install-infos
InstallInfos.update({"appname":str(pkgname)}) InstallInfos.update({"appname":str(pkgname)})
if pkgname in self.window_main.update_list.upgrade_meta.versoin_pkgs['single_upgrade'].keys(): if pkgname in self.window_main.main_meta.versoin_pkgs['single_upgrade'].keys():
InstallInfos.update({"old_version":str(self.window_main.update_list.upgrade_meta.versoin_pkgs['single_upgrade'][pkgname])}) InstallInfos.update({"old_version":str(self.window_main.main_meta.versoin_pkgs['single_upgrade'][pkgname])})
else: else:
InstallInfos.update({"old_version":'UnKnown'}) InstallInfos.update({"old_version":'UnKnown'})
InstallInfos.update({"new_version":str(pkgversion)}) InstallInfos.update({"new_version":str(pkgversion)})
InstallInfos.update({"status":status}) InstallInfos.update({"status":status})
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)}) InstallInfos.update({"errorCode":str(errorcode)})
InstallInfos.update({"error_string":str(error_string)})
InstallInfos.update({"error_desc":str(error_desc)})
self.window_main.collector.Upgrade_Process_Msg("finish-install", InstallInfos.copy()) self.window_main.collector.Upgrade_Process_Msg("finish-install", InstallInfos.copy())
# 软件商店获取中文名 # 软件商店获取中文名
appname_cn = self.get_cn_appname(str(pkgname)) appname_cn = self.get_cn_appname(str(pkgname))
#FIXME: 临时方案 PHP #FIXME: 临时方案 PHP
PHPSeverSend(_appname=pkgname, _appversion=pkgversion, _statue=status, _errorcode="10000100", _errorstring=errstr) PHPSeverSend(_appname=pkgname, _appversion=pkgversion, _statue=status, _errorcode=str(errorcode), _errorstring=errstr)
try: try:
self.insert_into_updateinfo(pkgname, pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn, status_cn, changeLog) self.insert_into_updateinfo(pkgname, pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn, status_cn, changeLog)
# FIXME: 发送插入数据库成功的信号local_upgrade_list # FIXME: 发送插入数据库成功的信号local_upgrade_list
@ -344,17 +416,21 @@ class Sqlite3Server(object):
UpdateInfos.update({"appname":str(pkg.name)}) UpdateInfos.update({"appname":str(pkg.name)})
UpdateInfos.update({"source":"Kylin System Updater"}) UpdateInfos.update({"source":"Kylin System Updater"})
UpdateInfos.update({"status":status}) UpdateInfos.update({"status":status})
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)}) UpdateInfos.update({"errorCode":str(errorcode)})
UpdateInfos.update({"error_string":str(error_string)})
UpdateInfos.update({"error_desc":str(error_desc)})
self.window_main.collector.Upgrade_Process_Msg("finish-update", UpdateInfos.copy()) self.window_main.collector.Upgrade_Process_Msg("finish-update", UpdateInfos.copy())
#安装信息install-infos #安装信息install-infos
InstallInfos.update({"appname":str(pkg.name)}) InstallInfos.update({"appname":str(pkg.name)})
if pkg.name in self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'].keys(): if pkg.name in self.window_main.main_meta.versoin_pkgs['groups_upgrade'].keys():
InstallInfos.update({"old_version":str(self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'][pkg.name])}) InstallInfos.update({"old_version":str(self.window_main.main_meta.versoin_pkgs['groups_upgrade'][pkg.name])})
else: else:
InstallInfos.update({"old_version":'UnKnown'}) InstallInfos.update({"old_version":'UnKnown'})
InstallInfos.update({"new_version":str(pkgversion)}) InstallInfos.update({"new_version":str(pkgversion)})
InstallInfos.update({"status":status}) InstallInfos.update({"status":status})
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)}) InstallInfos.update({"errorCode":str(errorcode)})
InstallInfos.update({"error_string":str(error_string)})
InstallInfos.update({"error_desc":str(error_desc)})
self.window_main.collector.Upgrade_Process_Msg("finish-install", InstallInfos.copy()) self.window_main.collector.Upgrade_Process_Msg("finish-install", InstallInfos.copy())
try: try:
@ -368,7 +444,7 @@ class Sqlite3Server(object):
self.insert_into_updateinfo(str(i), pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn, status_cn, changeLog) self.insert_into_updateinfo(str(i), pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn, status_cn, changeLog)
self.window_main.dbusController.UpdateSqlitSingle(str(i), timestr) self.window_main.dbusController.UpdateSqlitSingle(str(i), timestr)
#FIXME: 临时方案 PHP #FIXME: 临时方案 PHP
PHPSeverSend(_appname=pkg.name, _appversion=pkgversion, _statue=status, _errorcode="10000100", _errorstring=errstr) PHPSeverSend(_appname=pkg.name, _appversion=pkgversion, _statue=status, _errorcode=str(errorcode), _errorstring=errstr)
# insert group deb next # insert group deb next
for i in pkg_group: for i in pkg_group:
# FIXME: 获取组信息 # FIXME: 获取组信息
@ -377,17 +453,21 @@ class Sqlite3Server(object):
UpdateInfos.update({"appname":str(i)}) UpdateInfos.update({"appname":str(i)})
UpdateInfos.update({"source":"Kylin System Updater"}) UpdateInfos.update({"source":"Kylin System Updater"})
UpdateInfos.update({"status":status}) UpdateInfos.update({"status":status})
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)}) UpdateInfos.update({"errorCode":str(errorcode)})
UpdateInfos.update({"error_string":str(error_string)})
UpdateInfos.update({"error_desc":str(error_desc)})
self.window_main.collector.Upgrade_Process_Msg("finish-update", UpdateInfos.copy()) self.window_main.collector.Upgrade_Process_Msg("finish-update", UpdateInfos.copy())
#安装信息install-infos #安装信息install-infos
InstallInfos.update({"appname":str(i)}) InstallInfos.update({"appname":str(i)})
if i in self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'].keys(): if i in self.window_main.main_meta.versoin_pkgs['groups_upgrade'].keys():
InstallInfos.update({"old_version":str(self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'][i])}) InstallInfos.update({"old_version":str(self.window_main.main_meta.versoin_pkgs['groups_upgrade'][i])})
else: else:
InstallInfos.update({"old_version":'UnKnown'}) InstallInfos.update({"old_version":'UnKnown'})
InstallInfos.update({"new_version":str(pkgversion)}) InstallInfos.update({"new_version":str(pkgversion)})
InstallInfos.update({"status":status}) InstallInfos.update({"status":status})
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)}) InstallInfos.update({"errorCode":str(errorcode)})
InstallInfos.update({"error_string":str(error_string)})
InstallInfos.update({"error_desc":str(error_desc)})
json_file = json.dumps(InstallInfos.copy()) json_file = json.dumps(InstallInfos.copy())
try: try:
self.window_main.collector.UpdateMsg("InstallInfos", json_file) self.window_main.collector.UpdateMsg("InstallInfos", json_file)
@ -395,7 +475,7 @@ class Sqlite3Server(object):
pass pass
#FIXME: 临时方案 PHP #FIXME: 临时方案 PHP
PHPSeverSend(_appname=i, _appversion=pkgversion, _statue=status, _errorcode="10000100", _errorstring=errstr) PHPSeverSend(_appname=i, _appversion=pkgversion, _statue=status, _errorcode=str(errorcode), _errorstring=errstr)
file_path = os.path.join(get_config_patch(), str(i) + ".yaml") file_path = os.path.join(get_config_patch(), str(i) + ".yaml")
with open(file_path, "r") as stream: with open(file_path, "r") as stream:
try: try:
@ -435,6 +515,7 @@ class Sqlite3Server(object):
logging.warning("Cache is None.") logging.warning("Cache is None.")
except Exception as e: except Exception as e:
logging.error("record update error: %s.",str(e)) logging.error("record update error: %s.",str(e))
self.window_main.collector.Msg_Clean()
# 获取group信息 # 获取group信息
def GetGroupmsg(self, appname): def GetGroupmsg(self, appname):
@ -508,7 +589,7 @@ class Sqlite3Server(object):
sql = "select init_version from display where id=1" sql = "select init_version from display where id=1"
self.cursor.execute(sql) self.cursor.execute(sql)
_is_init_verison = self.cursor.fetchone()[0] _is_init_verison = self.cursor.fetchone()[0]
if _is_init_verison == "yes": if _is_init_verison == "yes" or _is_init_verison == "true":
update_version, os_version = self.get_default_version() update_version, os_version = self.get_default_version()
logging.info("Need to refresh version ...") logging.info("Need to refresh version ...")
self._refresh_system_version(update_version, os_version) self._refresh_system_version(update_version, os_version)
@ -517,7 +598,6 @@ class Sqlite3Server(object):
self.connect.commit() self.connect.commit()
except Exception as e: except Exception as e:
logging.error(str(e)) logging.error(str(e))
self.disconnect_database()
self.disconnect_database() self.disconnect_database()
def _refresh_system_version(self, update_version='', os_version = '', pseudo_version = False): def _refresh_system_version(self, update_version='', os_version = '', pseudo_version = False):
@ -526,8 +606,6 @@ class Sqlite3Server(object):
update_version = str(update_version).split('=')[-1] update_version = str(update_version).split('=')[-1]
if "=" in os_version: if "=" in os_version:
os_version = str(os_version).split('=')[-1] os_version = str(os_version).split('=')[-1]
os_version = os_version.strip()
update_version = update_version.strip()
#刷新系统版本号:os_version #刷新系统版本号:os_version
if update_version == '': if update_version == '':
@ -538,7 +616,7 @@ class Sqlite3Server(object):
for line in lines: for line in lines:
if "KYLIN_RELEASE_ID" in line: if "KYLIN_RELEASE_ID" in line:
os_version = line.split('=')[1] os_version = line.split('=')[1]
os_version = os_version.strip() os_version = os_version.strip().strip('"')
if not pseudo_version: if not pseudo_version:
if len(os_version) != 0: if len(os_version) != 0:
self.ucconfigs.setValue("SYSTEM","os_version",str(os_version),True) self.ucconfigs.setValue("SYSTEM","os_version",str(os_version),True)
@ -579,7 +657,7 @@ class Sqlite3Server(object):
for line in lines: for line in lines:
if "KYLIN_RELEASE_ID" in line: if "KYLIN_RELEASE_ID" in line:
os_version = line.split('=')[1] os_version = line.split('=')[1]
os_version = eval(os_version.strip()) os_version = os_version.strip().strip('"')
if update_version == "" and os_version != "": if update_version == "" and os_version != "":
update_version = os_version update_version = os_version
elif update_version != "" and os_version == "": elif update_version != "" and os_version == "":
@ -675,6 +753,268 @@ class Sqlite3Server(object):
except Exception as e: except Exception as e:
logging.error(e) logging.error(e)
return False return False
class DataMigration():
def __init__(self):
pass
#connect连接数据库
def connect_database(self):
try:
self.connect = sqlite3.connect(DB_FILE, check_same_thread=False)
self.cursor = self.connect.cursor()
except Exception as e:
logging.error("Failed to connect database: %s", str(e))
#disconnect连接数据库
def disconnect_database(self):
try:
if self.connect != None:
self.connect.close()
if self.connect != None:
del self.cursor
except Exception as e:
logging.error("Failed to disconnect database: %s", str(e))
def MarkFirstMigration(self):
if (os.path.exists(DB_UPGRADE)):
try:
new_db = sqlite3.connect(DB_UPGRADE, check_same_thread=False)
new_db_cursor = new_db.cursor()
if (self._has_first_migration(new_db, new_db_cursor)): # 存在 firstmigration
if (self._is_first_migration(new_db, new_db_cursor)):
sql_commnd = "UPDATE display SET firstmigration='false';"
new_db_cursor.execute(sql_commnd)
new_db.commit()
else:# 不存在firstmigration
# 新增 firstmigration 字段
sql_commnd = "alter table display add column firstmigration text;"
new_db_cursor.execute(sql_commnd)
sql_commnd = "UPDATE display SET firstmigration='false';"
new_db_cursor.execute(sql_commnd)
new_db.commit()
except Exception as e:
logging.error("Failed to disconnect database: %s", str(e))
else :
logging.info("Not found kylin-system-updater.db, ensure that \'kylin-system-updater\' is successfully installed ... ")
def CopyData(self):
# 判断数据库是否存在
if (os.path.exists(VER_DB) and os.path.exists(DB_UPGRADE)):
try:
new_db = sqlite3.connect(DB_UPGRADE, check_same_thread=False)
new_db_cursor = new_db.cursor()
ver_db = sqlite3.connect(VER_DB, check_same_thread=False)
ver_db_cursor = ver_db.cursor()
if (self._has_first_migration(new_db, new_db_cursor)): # 存在 firstmigration
if (self._is_first_migration(new_db, new_db_cursor)):
# 数据迁移
if (self.dateMigration(new_db=new_db, new_db_cursor=new_db_cursor)):
sql_commnd = "UPDATE display SET firstmigration='false';"
new_db_cursor.execute(sql_commnd)
new_db.commit()
else:
logging.info("No data migration is required ...")
else:# 不存在firstmigration
# 新增 firstmigration 字段
sql_commnd = "alter table display add column firstmigration text;"
new_db_cursor.execute(sql_commnd)
sql_commnd = "UPDATE display SET firstmigration='yes';"
new_db_cursor.execute(sql_commnd)
#数据迁移
if (self.dateMigration(new_db=new_db, new_db_cursor=new_db_cursor)):
sql_commnd = "UPDATE display SET firstmigration='false';"
new_db_cursor.execute(sql_commnd)
new_db.commit()
except Exception as e:
logging.error("Failed to disconnect database: %s", str(e))
else :
logging.info("Not found kylin-system-updater.db, ensure that \'kylin-system-updater\' is successfully installed ... ")
def _has_first_migration(self, new_db, new_db_cursor)->bool:
try:
sql_commnd = "select * from sqlite_master where type='table' and name='display';"
new_db_cursor.execute(sql_commnd)
retval = new_db_cursor.fetchone()
for rv in retval:
if "firstmigration" in str(rv):
return True
except Exception as e:
logging.error("Failed to get field firstMigration: %s", str(e))
return False
def _is_first_migration(self, new_db, new_db_cursor):
try:
sql_commnd = "select firstmigration from display;"
new_db_cursor.execute(sql_commnd)
retval = new_db_cursor.fetchone()
if "true" in retval or "yes" in retval:
return True
except Exception as e:
logging.error("Failed to select firstMigration: %s", str(e))
return False
def _is_display_exist_fields(self, field, db, db_cursor):
try:
sql_commnd = "select * from sqlite_master where type='table' and name='display';"
db_cursor.execute(sql_commnd)
retval = db_cursor.fetchone()
for rv in retval:
if field in str(rv):
return True
except Exception as e:
logging.error("Failed to select %s: %s", field, str(e))
return False
def _add_display_fields(self, fields_default):
try:
if "=" not in fields_default:
print("format: field=value")
return False
field, value = fields_default.split('=')
print(_("Loading Sqlite3Server..."))
db = sqlite3.connect(DB_UPGRADE, check_same_thread=False)
db_cursor = db.cursor()
if self._is_display_exist_fields(field, db, db_cursor):
print("field %s is exist."%field)
return False
# 字段不存在,新增字段
sql_commnd = "alter table display add column "+field+" TEXT;"
db_cursor.execute(sql_commnd)
sql_commnd = "UPDATE display SET "+field+"='"+value+"'"
db_cursor.execute(sql_commnd)
db.commit()
except Exception as e:
print(e)
return False
print("Succeeded in adding field: '%s' "%field)
return True
def dateMigration(self,new_db,new_db_cursor,old_db=None,old_db_cursor=None)->bool:
try:
if old_db==None and old_db_cursor==None:
old_db = sqlite3.connect(DB_UPDATER, check_same_thread=False)
old_db_cursor = old_db.cursor()
except Exception as e:
logging.error("Failed to dateMigration: %s", str(e))
return False
sql_commnd = ""
update_record_dict = {}
tmp_update_record_dict = []
# step 2: 获取更新数据
try:
sql_commnd = "SELECT * FROM installed"
old_db_cursor.execute(sql_commnd)
update_record = old_db_cursor.fetchall()
# sql_commnd = "SELECT * FROM updateinfos"
# new_db_cursor.execute(sql_commnd)
# new_update_record = new_db_cursor.fetchall()
for ur in update_record:
id,appname,version,time,description,icon,statue,keyword,errorcode = ur
if errorcode in range(200):
errorcode = 'null'
update_record_dict.clear()
update_record_dict.update({"appname":appname})
update_record_dict.update({"version":version})
update_record_dict.update({"time":time})
update_record_dict.update({"description":description})
update_record_dict.update({"icon":icon})
update_record_dict.update({"statue":statue})
update_record_dict.update({"keyword":'1'})
update_record_dict.update({"errorcode":errorcode})
tmp_update_record_dict.append(update_record_dict.copy())
# 按时间排序
tmp_update_record_dict = sorted(tmp_update_record_dict, key=itemgetter('time'))
except Exception as e:
logging.error("Failed to generate update records: %s", str(e))
return False
logging.info("Generate update records complete.")
# step 3: insert新生成的记录
try:
# 创建临时表
sql_commnd = "create table IF NOT EXISTS tmp('id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,\
'appname' TEXT,\
'version' TEXT,\
'description' TEXT,\
'date' TEXT,\
'status' TEXT,\
'keyword' TEXT,\
'errorcode' TEXT,\
'appname_cn' TEXT,\
'status_cn' TEXT,\
'changelog' TEXT) "
new_db_cursor.execute(sql_commnd)
# 更新数据
for urd in tmp_update_record_dict:
new_db_cursor.execute(
"insert into tmp (appname, version, description, date, status, keyword, errorcode) values(?,"
"?,?,?,?,?,?)",
(urd['appname'], urd['version'], urd['description'], urd['time'], urd['statue'], urd['keyword'], urd['errorcode']))
new_db.commit()
# 删除updateinfos
sql_commnd = "drop table updateinfos"
new_db_cursor.execute(sql_commnd)
new_db.commit()
# 修改表名
sql_commnd = "alter table tmp rename to updateinfos"
new_db_cursor.execute(sql_commnd)
new_db.commit()
except Exception as e:
logging.error("Failed to transfer data: %s", str(e))
return False
old_cfg_dict = {}
new_cfg_dict = {}
# step 4: 更新配置转移
try:
sql_commnd = "SELECT * FROM display where id=1"
old_db_cursor.execute(sql_commnd)
old_cfg = old_db_cursor.fetchone()
for od in old_db_cursor.description:
old_cfg_dict.update({str(od[0]):old_cfg[old_db_cursor.description.index(od)]})
if old_db != None:
old_db.close()
if old_db_cursor != None:
del old_db_cursor
new_db_cursor.execute(sql_commnd)
new_cfg = new_db_cursor.fetchone()
for od in new_db_cursor.description:
new_cfg_dict.update({str(od[0]):new_cfg[new_db_cursor.description.index(od)]})
sql_commnd = "UPDATE display set check_time='"+old_cfg_dict['check_time']+"' Where id=1"
new_db_cursor.execute(sql_commnd)
new_db.commit()
sql_commnd = "UPDATE display set update_time='"+old_cfg_dict['update_time']+"' Where id=1"
new_db_cursor.execute(sql_commnd)
new_db.commit()
sql_commnd = "UPDATE display set auto_check='"+old_cfg_dict['auto_check']+"' Where id=1"
new_db_cursor.execute(sql_commnd)
new_db.commit()
sql_commnd = "UPDATE display set system_version='"+old_cfg_dict['system_version']+"' Where id=1"
new_db_cursor.execute(sql_commnd)
new_db.commit()
if old_cfg_dict['auto_backup'] != None:
sql_commnd = "UPDATE display set auto_backup='"+old_cfg_dict['auto_backup']+"' Where id=1"
new_db_cursor.execute(sql_commnd)
new_db.commit()
if 'download_limit' in old_cfg_dict.keys() and old_cfg_dict['download_limit'] != None:
sql_commnd = "UPDATE display set download_limit='"+old_cfg_dict['download_limit']+"' Where id=1"
new_db_cursor.execute(sql_commnd)
new_db.commit()
if 'download_limit_value' in old_cfg_dict.keys() and old_cfg_dict['download_limit_value'] != None:
sql_commnd = "UPDATE display set download_limit_value='"+old_cfg_dict['download_limit_value']+"' Where id=1"
new_db_cursor.execute(sql_commnd)
new_db.commit()
except Exception as e:
print(e)
print("更新配置文件错误")
return
logging.info("The data migration is complete.")
return True return True
def listtojsonstr(lists): def listtojsonstr(lists):

View File

@ -0,0 +1,61 @@
#!/usr/bin/python3
# DistUpgradeConfigParser.py
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
import json
import logging
class Singleton(object):
def __init__(self, cls):
self._cls = cls
self._instance = {}
def __call__(self):
if self._cls not in self._instance:
self._instance[self._cls] = self._cls()
return self._instance[self._cls]
@Singleton
class JsonConfig():
NOW_UPDATE_CONFIG = '/usr/share/kylin-update-desktop-config/config/kylin-update-desktop-system.json'
def __init__(self):
self._configDate = None
self.read()
def read(self):
try:
with open(self.NOW_UPDATE_CONFIG,'r') as f:
logging.info("Reading json configuration file...")
self._configDate = json.load(f)
except Exception as exc:
logging.warning("Reading json configuration file,check json format...")
logging.warning(exc)
self._configDate = None
def getWithDefault(self,key1=None,key2=None,key3=None,key4=None,default=None):
try:
if self._configDate == None:
logging.warning("Reading json configuration file,check json format...")
return default
if key4 != None:
return self._configDate[key1][key2][key3][key4]
elif key3 != None:
return self._configDate[key1][key2][key3]
elif key2 != None:
return self._configDate[key1][key2]
elif key1 != None:
return self._configDate[key1]
else:
return self._configDate
except Exception as e:
logging.warning(str(e))
return default
if __name__ == "__main__":
# c = UpgradeConfig("/home/x/share/kylin-system-updater/backend/data/")
# print(c.setValue("SystemStatus", "abnormal_reboot", str(False)),True)
# print(c.getWithDefault("SystemStatus", "abnormal_reboot", False))
pass

View File

@ -0,0 +1,278 @@
#!/usr/bin/python3
import os
import logging
class LocalUpgradeDataList:
"""
Represent the (potentially partial) results of an unattended-upgrades
run
"""
def __init__(self):
#可升级的组列表
self._push_groups = []
self._push_steps = []
self._push_singles = []
self._pkgs_data = {}
#加版本号的升级包
self.versoin_pkgs = {'single_upgrade':{}, 'groups_upgrade':{}}
self._problem_resolver = {}
self.steps_queue = []
self.last_task = ''
self.resolver_name = "total_pkgs"
if "en_US" in os.environ["LANG"]:
self.lang = "en_US"
else:
self.lang = "zh_CN"
def refresh(self):
self._push_groups = []
self._push_steps = []
self._push_singles = []
self._pkgs_data = {}
#加版本号的升级包
self.versoin_pkgs = {'single_upgrade':{}, 'groups_upgrade':{}}
self._problem_resolver = {}
self.steps_queue = []
self.last_task = ''
if "en_US" in os.environ["LANG"]:
self.lang = "en_US"
else:
self.lang = "zh_CN"
#单包推送
def add_singles(self,pkgs):
self._push_singles = pkgs
def get_singles(self):
return self._push_singles
#分步推送 添加分步数据
def add_steps(self,groups,data):
self._push_steps.append(groups)
self._pkgs_data.update(data)
def get_steps(self):
return self._push_steps
#组推送
def add_groups(self,groups,data):
self._push_groups.append(groups)
self._pkgs_data.update(data)
def get_groups(self):
return self._push_groups
#获取所以推送的升级
def get_push(self):
return self._push_groups + self._push_singles
def is_steps(self,content):
for cont in content:
if cont in self._push_singles:
return False
if self._push_steps == []:
return False
else:
return True
def check_steps_reboot(self,content):
return self._pkgs_data.get(content,{}).get('need_reboot',False)
def get_pkgs_total(self,cache):
pkgs_install = []
pkgs_upgrade = []
#单包的升级方式
for pkg in self._push_singles:
if cache[pkg].is_installed:
pkgs_upgrade.append(pkg)
else:
pkgs_install.append(pkg)
#遍历升级组列表
for group_name in self._push_groups:
pkgs_install += self._pkgs_data.get(group_name,{}).get('install_list',[])
pkgs_upgrade += self._pkgs_data.get(group_name,{}).get('upgrade_list',[])
return pkgs_install,pkgs_upgrade
def get_steps_pkgs(self,step_name):
pkgs_install = []
pkgs_upgrade = []
pkgs_install += self._pkgs_data.get(step_name,{}).get('install_list',[])
pkgs_upgrade += self._pkgs_data.get(step_name,{}).get('upgrade_list',[])
return pkgs_install,pkgs_upgrade
def get_push_pkgs(self,content):
pkgs_install = []
pkgs_upgrade = []
if content == []:
for group_name in self._push_groups:
pkgs_install += self._pkgs_data.get(group_name,{}).get('pkgs_install',[])
pkgs_upgrade += self._pkgs_data.get(group_name,{}).get('pkgs_upgrade',[])
if self._push_singles != []:
pkgs_upgrade += self._push_singles
else:
for cont in content:
if cont in self._push_groups:
pkgs_install += self._pkgs_data.get(cont,{}).get('pkgs_install',[])
pkgs_upgrade += self._pkgs_data.get(cont,{}).get('pkgs_upgrade',[])
if cont in self._push_singles:
pkgs_upgrade.append(cont)
return pkgs_install,pkgs_upgrade
#将要升级的内容
def _make_upgrade_content(self,content):
if content == []:
return self._push_groups + self._push_singles
else:
return content
def resolver_groups(self,pkgs_install,pkgs_upgrade,pkgs_remove):
put_data = {self.resolver_name:{'install_pkgs':pkgs_install,'upgrade_pkgs':pkgs_upgrade,'reomve_pkgs':pkgs_remove}}
self._problem_resolver.update(put_data)
def resolver_steps(self,step_name,pkgs_install,pkgs_upgrade,pkgs_remove):
put_data = {step_name:{'install_pkgs':pkgs_install,'upgrade_pkgs':pkgs_upgrade,'reomve_pkgs':pkgs_remove}}
self._problem_resolver.update(put_data)
def classify_content(self,content):
if content == []:
return self._push_singles.copy(),self._push_groups.copy()
else:
for cont in content:
if cont in self._push_singles.copy():
return content,[]
elif cont in self._push_groups.copy():
return [],content
else:
return [],[]
def get_resolver_upgrade(self):
pkgs_install = []
pkgs_upgrade = []
pkgs_remove = []
pkgs_install = self._problem_resolver.get(self.resolver_name,{}).get('install_pkgs',[])
pkgs_upgrade = self._problem_resolver.get(self.resolver_name,{}).get('upgrade_pkgs',[])
pkgs_remove = self._problem_resolver.get(self.resolver_name,{}).get('reomve_pkgs',[])
return pkgs_install,pkgs_upgrade,pkgs_remove
def get_progress(self,content):
#为了 解决获取包列表和获取进度传输的数据不能协同的问题
if content == self.resolver_name:
for groups in self._push_groups:
content = groups
break
begin = self._pkgs_data.get(content,{}).get('progress_begin',0)
end = self._pkgs_data.get(content,{}).get('progress_end',0)
return begin,end
def pop(self,content):
for cont in content:
if cont in self._push_singles:
self._push_singles.remove(cont)
if cont in self._push_groups:
self._push_groups.remove(cont)
def get_resolver_steps(self,content):
pkgs_install = []
pkgs_upgrade = []
pkgs_remove = []
pkgs_install = self._problem_resolver.get(content,{}).get('install_pkgs',[])
pkgs_upgrade = self._problem_resolver.get(content,{}).get('upgrade_pkgs',[])
pkgs_remove = self._problem_resolver.get(content,{}).get('reomve_pkgs',[])
return pkgs_install,pkgs_upgrade,pkgs_remove
#升级完成后从升级列表删除
def reset_push_content(self,content):
for cont in content:
if cont in self._push_singles:
self._push_singles.remove(cont)
if cont in self._push_groups:
self._push_groups.remove(cont)
def get_post_notify(self):
notify = self._pkgs_data.get(self.last_task,{}).get("users_notify",{}).get("post_install_notify",None)
if notify == None:
return ''
return notify.get(self.lang,'')
def get_mid_notify(self,content):
notify = self._pkgs_data.get(content,{}).get("users_notify",{}).get("mid_install_notify",None)
if notify == None:
return ''
return notify.get(self.lang,'')
def get_pre_script(self,content):
script_list = []
if content == self.resolver_name:
for groups in self._push_groups:
content = groups
break
script = self._pkgs_data.get(content,{}).get("script",None)
if script == None:
return script_list
for scr in ["pre_update_status_check","pre_update_script"]:
run_path = script.get(scr,[])
if isinstance(run_path,list) == True:
for sc in run_path:
if sc != '':
script_list.append(sc)
elif isinstance(run_path,str) == True:
if run_path != '':
script_list.append(run_path)
else:
pass
return script_list
def get_post_script(self,content):
script_list = []
if content == self.resolver_name:
for groups in self._push_groups:
content = groups
break
script = self._pkgs_data.get(content,{}).get("script",None)
if script == None:
return script_list
for scr in ["post_update_status_check","post_update_script"]:
run_path = script.get(scr,[])
if isinstance(run_path,list) == True:
for sc in run_path:
if sc != '':
script_list.append(sc)
elif isinstance(run_path,str) == True:
if run_path != '':
script_list.append(run_path)
else:
pass
return script_list

View File

@ -0,0 +1,402 @@
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# 脚本插件化执行管理
# TODO:
# 使能/失能 --配置文件--ok
# 错误码 --脚本/本程序--wait/add
# 进度同步 --线程获取--add
# 输出规范 --脚本/本程序(重定向日志文件、输出格式)--ok/ok
# 元数据类型 --描述信息、翻译(配置文件)--ok
# 运行等级 --(root/user)--wait
import subprocess
import os
from sre_compile import isstring
import threading
import yaml
import logging
from gi.repository import GObject
class pluginState():
PLUGIN_SUCCESS = 0
PLUGINERR_PLUGIN_NOT_EXIST = PLUGIN_SUCCESS - 1
PLUGINERR_PLUGIN_NOT_COMPLETED = PLUGINERR_PLUGIN_NOT_EXIST - 1
PLUGINERR_NO_AVAILABLE_YAML = PLUGINERR_PLUGIN_NOT_COMPLETED - 1
PLUGINERR_NOT_LOAD_ALL = PLUGINERR_NO_AVAILABLE_YAML - 1
PLUGINERR_PLUGIN_NOT_IN_LIST = PLUGINERR_NOT_LOAD_ALL - 1
PLUGINERR_PLUGIN_NOT_ENABLED = PLUGINERR_PLUGIN_NOT_IN_LIST - 1
PLUGINERR_PLUGIN_CONFIG_FAILED = PLUGINERR_PLUGIN_NOT_ENABLED - 1
PLUGINERR_LOG_PATH_NOT_EXIT = PLUGINERR_PLUGIN_CONFIG_FAILED - 1
PLUGINERR_CONFIG_NOT_COMPLETED = PLUGINERR_LOG_PATH_NOT_EXIT - 1
PLUGINERR_CMD_IS_NONE = PLUGINERR_CONFIG_NOT_COMPLETED - 1
PLUGINERR_LANGUAGE_NOT_SUPPORT = PLUGINERR_CMD_IS_NONE - 1
_numToInfo = {
PLUGIN_SUCCESS: 'success',
PLUGINERR_PLUGIN_NOT_EXIST: 'plugin path not exist',
PLUGINERR_PLUGIN_NOT_COMPLETED: 'plugin folder not completed',
PLUGINERR_NO_AVAILABLE_YAML: 'there is no available yaml',
PLUGINERR_NOT_LOAD_ALL: 'not run load_all',
PLUGINERR_PLUGIN_NOT_IN_LIST: 'plugin not in loaded plugin list',
PLUGINERR_PLUGIN_NOT_ENABLED: 'plugin not enabled',
PLUGINERR_PLUGIN_CONFIG_FAILED: 'plugin config failed',
PLUGINERR_LOG_PATH_NOT_EXIT: 'log path not exists',
PLUGINERR_CONFIG_NOT_COMPLETED: 'config not completed',
PLUGINERR_CMD_IS_NONE: 'cmd is none',
PLUGINERR_LANGUAGE_NOT_SUPPORT: 'not support this language',
}
_infoToNum = {
'success': PLUGIN_SUCCESS,
'plugin path not exist': PLUGINERR_PLUGIN_NOT_EXIST,
'plugin folder not completed': PLUGINERR_PLUGIN_NOT_COMPLETED,
'there is no available yaml': PLUGINERR_NO_AVAILABLE_YAML,
'not run load_all': PLUGINERR_NOT_LOAD_ALL,
'plugin not in loaded plugin list': PLUGINERR_PLUGIN_NOT_IN_LIST,
'plugin not enabled': PLUGINERR_PLUGIN_NOT_ENABLED,
'plugin config failed': PLUGINERR_PLUGIN_CONFIG_FAILED,
'log path not exists': PLUGINERR_LOG_PATH_NOT_EXIT,
'config not completed': PLUGINERR_CONFIG_NOT_COMPLETED,
'cmd is none': PLUGINERR_CMD_IS_NONE,
'not support this language': PLUGINERR_LANGUAGE_NOT_SUPPORT,
}
PLUGIN_MANAGER_PATH = "./" # 可修改
# 目录结构 FILE PATH
CFG_FILE = "conf.yaml"
CFG_EX_DIR = "conf.d/"
CFG_PATH = PLUGIN_MANAGER_PATH + CFG_FILE
CFG_EX_PATH = PLUGIN_MANAGER_PATH + CFG_EX_DIR
MOD_DIR = "modules/"
MOD_PATH = PLUGIN_MANAGER_PATH + MOD_DIR
MOD_AVAILABLE = "modules-available/"
MOD_ENABLED = "modules-enabled/"
MOD_AVAILABLE_PATH = MOD_PATH + MOD_AVAILABLE
MOD_ENABLED_PATH = MOD_PATH + MOD_ENABLED
PLUGIN_DIR = "script/"
PLUGIN_PATH = PLUGIN_MANAGER_PATH + PLUGIN_DIR
# 配置 日志路径
LOG_DIR_ROOT = '/var/log/kylin-system-updater/'
# 默认插件日志路径
PLUGIN_LOG_DIR = '/var/log/kylin-system-updater/plugin/'
# PLUGIN.YAML
PLUGIN_CONF_KEY_NAME = 'name'
PLUGIN_CONF_KEY_DESC = 'desc'
PLUGIN_CONF_KEY_EXEC = 'exec'
PLUGIN_CONF_KEY_LOGLEVEL = 'loglevel'
PLUGIN_CONF_KEY_RUNLEVEL = 'runlevel'
PLUGIN_CONF_KEY_LIST = [PLUGIN_CONF_KEY_NAME,PLUGIN_CONF_KEY_DESC,PLUGIN_CONF_KEY_EXEC,PLUGIN_CONF_KEY_LOGLEVEL,PLUGIN_CONF_KEY_RUNLEVEL]
# CONF.YAML AND CONF.D
MANAGER_CONF_KEY_LOGDIR = "logdir"
MANAGER_CONF_KEY_LIST = [MANAGER_CONF_KEY_LOGDIR, ]
FORMAT = "%(asctime)s [%(levelname)s]: %(message)s"
RUNLEVEL_LIST = ['ROOT', 'USER']
LOGLEVEL_LIST = ['DEBUG', 'INFO', 'NOTIFY', 'WARNING', 'ERROR', 'CRITICAL']
class LOADSTATE():
PLGNAME = 0x01
EXECCMD = 0x02
STATESUM = PLGNAME + EXECCMD
LANG_KEY_ZH_CN = 'zh_CN'
LANG_KEY_EN = 'en'
class LANGLIST():
LANG_EN = 0
LANG_ZH_CN = 1
class pluginClass(pluginState):
def __init__(self):
# 必须配置项
self.pluginName = None
self.execCmd = None
# 可选配置项
self.descList = [] # en / zh
self.logLevel = LOGLEVEL_LIST.index('DEBUG')
self.runLevel = RUNLEVEL_LIST.index('ROOT')
self.enabled = False
# 合成变量
self.cmd = None
self.logDir = PLUGIN_LOG_DIR # 插件日志路径
self.logPath = os.path.join(self.logDir, "default.log") # 插件日志文件
self.fifoName = "default-fifo" # 插件进度文件
# self.fifoPath = PLUGIN_PATH + self.fifoName
self.fifoPath = "/var/log/kylin-system-updater"+self.fifoName
# 记录变量
self.running = False # 是否在运行
self.process = 0 # 执行进度
self.loadState = 0 # 插件配置完成
logging.info("init finished.")
###################### 内部函数 ######################
# 1-配置指定字段
# 2-更新进度 (1/0.5s)
# 3-
######################
def _config_key(self, cfg, key):
if cfg == None or key == None or key not in cfg:
logging.warning("[PLUGIN]: key[%s] not in yaml.", key)
if key == PLUGIN_CONF_KEY_NAME:
if isstring(cfg[key]):
self.pluginName = cfg[key]
self.fifoName = cfg[key] + "-fifo"
self.loadState += LOADSTATE.PLGNAME
else:
logging.error("[PLUGIN]: name[%s] not string.", cfg[key])
elif key == PLUGIN_CONF_KEY_DESC:
langList = cfg[key]
descDict = {}
if langList == None or len(langList) == 0:
return
for i in range(len(langList)):
descDict = langList[i]
if LANG_KEY_EN in descDict:
self.descList.insert(LANGLIST.LANG_EN, descDict.pop(LANG_KEY_EN))
continue
elif LANG_KEY_ZH_CN in descDict:
self.descList.insert(LANGLIST.LANG_ZH_CN, descDict.pop(LANG_KEY_ZH_CN))
continue
elif key == PLUGIN_CONF_KEY_EXEC:
if isstring(cfg[key]):
self.execCmd = cfg[key]
self.loadState += LOADSTATE.EXECCMD
else:
logging.error("[PLUGIN]: execCmd[%s] not string.", cfg[key])
elif key == PLUGIN_CONF_KEY_LOGLEVEL:
loglevel = cfg[key].upper()
if loglevel in LOGLEVEL_LIST:
self.logLevel = LOGLEVEL_LIST.index(loglevel)
elif key == PLUGIN_CONF_KEY_RUNLEVEL:
runlevel = cfg[key].upper()
if runlevel in RUNLEVEL_LIST:
self.runLevel = RUNLEVEL_LIST.index(runlevel)
else:
logging.warning("[PLUGIN]: key[%s] not need config.", key)
def _update_process(self):
if not self.running:
logging.info("[PLUGIN]: plugin [%s] is not running.", self.pluginName)
return
if os.path.exists(self.fifoPath):
try:
fd = open(self.fifoPath, 'r', 1)
process = fd.readline()
self.process = int(process.strip("\n"))
except Exception as e:
logging.info("[PLUGIN]: get process err[%s].",e)
else:
logging.info("[PLUGIN]: fifo[%s] not exists.", self.fifoPath)
if self.process >= 100 or self.process < 0:
return
tmptimer = threading.Timer(0.5, function=self._update_process)
tmptimer.start()
###################### 外部函数 ######################
# 1-读取配置文件,并配置该插件
# 2-使能插件
# 3-失能插件
# 4-获取插件名称
# 5-获取进度
# 6-注册进度跟新回调
# 7-执行插件
# 8-获取描述信息
# 9-设置脚本日志路径
# TODO:
# 重配置该插件
######################
# 配置该插件
def plg_config(self, filePath):
if not os.path.exists(filePath):
logging.error("[PLUGIN]: [%s] not exist.", filePath)
return self.PLUGINERR_PLUGIN_CONFIG_FAILED
def plg_enable(self):
self.enabled = True
def plg_disable(self):
self.enabled = False
def plg_get_name(self):
return self.pluginName
def plg_get_process(self):
return self.process
def plg_get_desc(self):
# 获得语言变量
#TODO: 例如:中文繁体,如果不存在的话,显示中文简体
lang=os.getenv("LANG")
if LANG_KEY_EN in lang:
if len(self.descList) > LANGLIST.LANG_EN:
return self.descList[LANGLIST.LANG_EN]
else:
logging.error("[PLUGIN]: There is not a desc of the language[%s].", lang)
elif LANG_KEY_ZH_CN in lang:
if len(self.descList) > LANGLIST.LANG_ZH_CN:
return self.descList[LANGLIST.LANG_ZH_CN]
else:
logging.error("[PLUGIN]: There is not a desc of the language[%s].", lang)
else:
logging.error("[PLUGIN]: There is not a desc of the language[%s].", lang)
return
# 添加 update cmd
# 设置脚本日志路径
def plg_set_logDir(self, logPath):
if not os.path.exists(logPath):
try:
os.makedirs(logPath, mode=0o755)
except Exception as e:
logging.error("[PLUGIN]: create plugin log dir failed.[%s]", e)
return self.PLUGINERR_LOG_PATH_NOT_EXIT
self.logDir = logPath
if self.pluginName != None:
self.logPath = os.path.join(self.logDir, self.pluginName + ".log")
self.cmd = "bash " + self.execCmd + " fifoname=" + self.fifoName + " logpath=" + self.logPath + " loglevel=" + str(self.logLevel) + " modename=" + self.pluginName
def plg_run(self):
if not self.enabled:
logging.error("[PLUGIN]: [%s] not enabled.", self.pluginName)
return self.PLUGINERR_PLUGIN_NOT_ENABLED
self.running = True
tmptimer = threading.Timer(0.5, function=self._update_process)
tmptimer.start()
if self.cmd == None:
logging.error("[PLUGIN]: cmd is None.")
return self.PLUGINERR_CMD_IS_NONE, self._numToInfo(self.PLUGINERR_CMD_IS_NONE), self._numToInfo(self.PLUGINERR_CMD_IS_NONE)
logging.debug("[PLUGIN]: cmd[%s].",self.cmd)
try:
ret = subprocess.run(self.cmd, shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
except Exception as e:
logging.error("[PLUGIN]: subprocess run err[%s].", e)
self.running = False
logging.debug("[PLUGIN]: [%s] run finished ret[%d].",self.pluginName, ret.returncode)
return ret.returncode, ret.stdout.decode(), ret.stderr.decode()
def plg_reconfig(self):
pass
class pluginManagerClass(pluginState):
def __init__(self):
# 变量初始化
self.plgClassList = [] # 插件句柄
self.loaded = False
self.managerLogDir = LOG_DIR_ROOT # 管理器日志路径
# 日志配置初始化,试用updater的logger
# if not os.path.exists(self.managerLogDir):
# os.mkdir(self.managerLogDir, mode=0o755)
# logfile = os.path.join(self.managerLogDir, 'PluginManager.log.' + str(self.classNum))
# logging.basicConfig(format=FORMAT, level='DEBUG', datefmt='%m-%d,%H:%M:%S', filename=logfile, filemode='a')
# self.pluginLogDir = PLUGIN_LOG_DIR # 插件日志路径
# 将单个插件句柄添加到全局记录, 并使能
def _add_single_plugin(self, filePath, enable):
if not os.path.exists(filePath):
logging.debug("[PLUGIN]: [%s] not exist.", filePath)
return
singlePlgClass = pluginClass()
singlePlgClass.plg_config(filePath)
self.plgClassList.append(singlePlgClass)
if enable:
singlePlgClass.plg_enable()
singlePlgClass.plg_set_logDir(self.pluginLogDir)
def _remove_single_plugin(self, pluginClass):
if pluginClass in self.plgClassList:
logging.debug("[PLUGIN]: remove [%s].", pluginClass.plg_get_name())
pluginClass.remove(pluginClass)
pluginClass.plg_disable()
# 加载所有插件,读取所有配置
# 第一个执行
# 返回插件句柄列表
# TODO:加载指定插件, 读取指定配置
def reload_plugin(self, pluginName):
pass
# 通过句柄获取插件名称
def get_plugin_name(self, pluginClass):
if not self.loaded:
logging.error("[PLUGIN]: please run load_all first.")
return self.PLUGINERR_NOT_LOAD_ALL
if pluginClass not in self.plgClassList:
logging.error("[PLUGIN]: there is no this plugin in pluginList.")
return self.PLUGINERR_PLUGIN_NOT_IN_LIST
return pluginClass.plg_get_name()
# 运行指定插件
# pluginName, pluginClass 都指定时,以名称为准
def run_plugin(self, pluginName = None):
self.running = True
if pluginName == None or not os.path.isfile(pluginName):
logging.error("[PLUGIN]: [%s] Cann't found.",pluginName)
return True
cmd = "bash " + pluginName
try:
ret = subprocess.run(cmd, shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
logging.info("[PLUGIN]: script[%s].",pluginName)
except Exception as e:
logging.error("[PLUGIN]: subprocess run err[%s].", e)
return True
self.running = False
if ret.returncode != 0:
logging.error("[PLUGIN]: code:%d, out:%s, err:%s",ret.returncode, ret.stdout.decode(), ret.stderr.decode())
logging.debug("[PLUGIN]: run finished returncode[%d], out[%s], err[%s]",ret.returncode, ret.stdout.decode(), ret.stderr.decode())
return (ret.returncode==0)
def connect_signal(self, plgclass, signal, handler):
if plgclass not in self.plgClassList:
logging.error("[PLUGIN]: there is no this plugin in pluginList.")
return self.PLUGINERR_PLUGIN_NOT_IN_LIST
return plgclass.connect(signal, handler)
def plugin_process_handler(obj, process):
logging.info("[PLUGIN]: ******* process [%d].", process)
# if __name__ == "__main__":
# pMClass = pluginManagerClass()
# plgList = pMClass.load_all("./")
# for everyPlg in iter(plgList):
# name = pMClass.get_plugin_name(everyPlg)
# print("name:", name)
# desc = pMClass.get_desc(everyPlg)
# print("desc:", desc)
# pMClass.connect_signal(everyPlg, "processChanged", plugin_process_handler)
# ret = pMClass.run_plugin(name)
# exit(0)

View File

@ -7,42 +7,19 @@ import json
import yaml import yaml
import shutil import shutil
from gi.repository import Gio from gi.repository import Gio
from .OriginFilter import UpdateListFilterCache
from .errors import * from .errors import *
from .enums import * from .enums import *
from SystemUpdater.Core.utils import get_config_patch from SystemUpdater.Core.utils import get_config_patch
class LocalUpgradeDataList:
"""
Represent the (potentially partial) results of an unattended-upgrades
run
"""
def __init__(self,
groups_pkgs={},
upgrade_groups=[],
single_pkgs=[],
adjust_pkgs=[],
):
#可升级的组列表
self.upgrade_groups = upgrade_groups
#组列表中包含的包
self.groups_pkgs = groups_pkgs
#推送的可升级的单包
self.single_pkgs = single_pkgs
#调整版本列表 源过滤
self.adjust_pkgs = adjust_pkgs
#加版本号的升级包
self.versoin_pkgs = {'single_upgrade':{}, 'groups_upgrade':{}}
class UpdateList(): class UpdateList():
OUTPUT_CONFIG_PATH = '/var/lib/kylin-system-updater/json/' OUTPUT_JSON_PATH = '/var/lib/kylin-system-updater/json/'
IMPORTANT_LIST_PATH = '/var/lib/kylin-software-properties/template/important.list' IMPORTANT_LIST_PATH = '/var/lib/kylin-software-properties/template/important.list'
def __init__(self,parent): def __init__(self,parent):
self.parent = parent self.parent = parent
#所有的组升级安装列表 #所有的组升级安装列表
self.upgrade_meta = LocalUpgradeDataList({},[],[],[]) self.update_meta = self.parent.main_meta
if 'XDG_CURRENT_DESKTOP' in os.environ: if 'XDG_CURRENT_DESKTOP' in os.environ:
self.current_desktop = os.environ.get('XDG_CURRENT_DESKTOP') self.current_desktop = os.environ.get('XDG_CURRENT_DESKTOP')
@ -57,31 +34,21 @@ class UpdateList():
self.application_dirs = [os.path.join(base, 'applications') self.application_dirs = [os.path.join(base, 'applications')
for base in data_dirs.split(':')] for base in data_dirs.split(':')]
self.config_path = get_config_patch()
if self.parent.install_mode.check_filter() == True:
#开启原过滤
self.fu = UpdateListFilterCache(self.parent)
else:
self.fu = None
logging.info("Close to Allowed origin fiter...")
#清空上次输出的分组JSON文件 #清空上次输出的分组JSON文件
def _empty_output_dir(self): def _empty_output_dir(self,path):
#清空 升级列表 #清空 升级列表
if not os.path.exists(self.OUTPUT_CONFIG_PATH): if not os.path.exists(path):
os.makedirs(self.OUTPUT_CONFIG_PATH) os.makedirs(path)
logging.info('making the ConfigPath(%s) is complete...',self.OUTPUT_CONFIG_PATH) logging.info('making the ConfigPath(%s) is complete...',path)
else: else:
shutil.rmtree(self.OUTPUT_CONFIG_PATH) shutil.rmtree(path)
os.makedirs(self.OUTPUT_CONFIG_PATH) os.makedirs(path)
logging.info('Emptying the ConfigPath(%s) is complete...',self.OUTPUT_CONFIG_PATH) logging.info('Emptying the ConfigPath(%s) is complete...',path)
#读取推送列表,判断分组和单包推送,再进行源过滤 #读取推送列表,判断分组和单包推送,再进行源过滤
def _make_important_list(self,cache,pkgs_upgrade,important_list = []): def _make_important_list(self,cache,pkgs_upgrade,important_list = []):
upgradeable_pkgs = [] upgradeable_pkgs = []
tmp = [] # tmp = []
upgradeable_groups = [] upgradeable_groups = []
logging.info("The Server Push List: %a",important_list) logging.info("The Server Push List: %a",important_list)
@ -94,17 +61,12 @@ class UpdateList():
if pkg_obj.is_installed: if pkg_obj.is_installed:
if pkg_name in pkgs_upgrade: if pkg_name in pkgs_upgrade:
pkgs_upgrade.remove(pkg_name) pkgs_upgrade.remove(pkg_name)
tmp.append(pkg_obj) upgradeable_pkgs.append(pkg_obj.name)
else: else:
tmp.append(pkg_obj) upgradeable_pkgs.append(pkg_obj.name)
else: else:
upgradeable_groups.append(pkg_name) upgradeable_groups.append(pkg_name)
if tmp != []:
install_list,upgrade_list,adjust_pkgs = self._make_fiter_origin(tmp,True)
self.upgrade_meta.adjust_pkgs.extend(adjust_pkgs)
upgradeable_pkgs = install_list + upgrade_list
logging.info("Push Single Packages: %a, Push Groups:%a",upgradeable_pkgs,upgradeable_groups) logging.info("Push Single Packages: %a, Push Groups:%a",upgradeable_pkgs,upgradeable_groups)
return upgradeable_groups,upgradeable_pkgs return upgradeable_groups,upgradeable_pkgs
@ -144,12 +106,12 @@ class UpdateList():
pass pass
return new_pkgs_list return new_pkgs_list
def _make_group_output_json(self,data,data_yaml,upgrade_pkgs_json,install_pkgs_json): def _make_group_output_json(self,data,data_yaml,upgrade_pkgs_json,install_pkgs_json,output_path):
groups_base_info = {} groups_base_info = {}
output_json = {} output_json = {}
#FIXME: 确定输出文件的文件名 以及放置位置 #FIXME: 确定输出文件的文件名 以及放置位置
output_config_name = self.OUTPUT_CONFIG_PATH + data['package'] + '.json' output_config_name = output_path + data['package'] + '.json'
#4、添加一些基础信息 #4、添加一些基础信息
groups_base_info.update({"package":data['package']}) groups_base_info.update({"package":data['package']})
@ -173,56 +135,11 @@ class UpdateList():
json.dump(output_json, f, ensure_ascii=False, indent=4) json.dump(output_json, f, ensure_ascii=False, indent=4)
logging.info("Generate Jsonfile(%s) to complete... ",output_config_name) logging.info("Generate Jsonfile(%s) to complete... ",output_config_name)
#进行源过滤is_adjust 是否调整cache中的候选版本单包推送会调整保持控制面板显示正确的版本
def _make_fiter_origin(self,pkgs_list,adjust_versions):
install_pkgs = []
upgrade_pkgs = []
adjust_pkgs = []
#是否进行源过滤的选项
if self.fu != None:
try:
after_pkgs_list,adjust_pkgs = self.fu.check_in_allowed_origin(pkgs_list,adjust_versions)
except Exception as e:
after_pkgs_list = pkgs_list
logging.error("Check Allowed origin is occur error:" + str(e))
else:
after_pkgs_list = pkgs_list
adjust_pkgs = []
for pkg_obj in after_pkgs_list:
if pkg_obj.is_installed:
upgrade_pkgs.append(pkg_obj.name)
else:
install_pkgs.append(pkg_obj.name)
return install_pkgs,upgrade_pkgs,adjust_pkgs
#从本地中获取本次升级需要升级的包 部分升级和全部升级使用 全盘升级不适用
def _make_pkgs_list(self,cache,groups_pkgs,groups_list,pkg_list):
pkgs_install = []
pkgs_upgrade = []
#单包的升级方式
for pkg in pkg_list:
if cache[pkg].is_installed:
pkgs_upgrade.append(pkg)
else:
pkgs_install.append(pkg)
#遍历升级组列表
for group_name in groups_list:
pkgs_install += groups_pkgs.get(group_name,[]).get('pkgs_install',[])
pkgs_upgrade += groups_pkgs.get(group_name,[]).get('pkgs_upgrade',[])
return pkgs_install,pkgs_upgrade
#输出白名单的配置 #输出白名单的配置
def _make_autoupgrade_config(self,cache,upgrade_data,_adjust_pkgs): def _make_autoupgrade_config(self,cache,output_path,config_path):
pkgs_install,pkgs_upgrade = self._make_pkgs_list(cache,upgrade_data.groups_pkgs,upgrade_data.upgrade_groups,upgrade_data.single_pkgs) pkgs_install,pkgs_upgrade = self.update_meta.get_pkgs_total(cache)
split_adjust_pkgs = [i.split("=")[0] for i in _adjust_pkgs]
output_config_name = self.OUTPUT_CONFIG_PATH + 'auto-upgrade-list.json' output_config_name = output_path + 'auto-upgrade-list.json'
output_json = {} output_json = {}
install_info = {} install_info = {}
for pkg in pkgs_install: for pkg in pkgs_install:
@ -230,11 +147,7 @@ class UpdateList():
pkgs_json = {} pkgs_json = {}
pkgs_json.update({"cur_version":getattr(pkg_cache.installed, "version", '')}) pkgs_json.update({"cur_version":getattr(pkg_cache.installed, "version", '')})
if pkg in split_adjust_pkgs: pkgs_json.update({"new_version":getattr(pkg_cache.candidate, "version", '')})
version_adjust = _adjust_pkgs[split_adjust_pkgs.index(pkg)].split("=")[1]
pkgs_json.update({"new_version":version_adjust})
else:
pkgs_json.update({"new_version":getattr(pkg_cache.candidate, "version", '')})
install_info.update({pkg:pkgs_json}) install_info.update({pkg:pkgs_json})
upgrade_json = {} upgrade_json = {}
@ -243,18 +156,14 @@ class UpdateList():
pkgs_json = {} pkgs_json = {}
pkgs_json.update({"cur_version":getattr(pkg_cache.installed, "version", '')}) pkgs_json.update({"cur_version":getattr(pkg_cache.installed, "version", '')})
if pkg in split_adjust_pkgs: pkgs_json.update({"new_version":getattr(pkg_cache.candidate, "version", '')})
version_adjust = _adjust_pkgs[split_adjust_pkgs.index(pkg)].split("=")[1]
pkgs_json.update({"new_version":version_adjust})
else:
pkgs_json.update({"new_version":getattr(pkg_cache.candidate, "version", '')})
upgrade_json.update({pkg:pkgs_json}) upgrade_json.update({pkg:pkgs_json})
group_json = {} group_json = {}
for ug in self.upgrade_meta.groups_pkgs: for ug in self.update_meta.get_groups():
pkgs_json = {} pkgs_json = {}
with open(self.config_path + str(ug) + ".yaml", "r") as stream: with open(config_path + str(ug) + ".yaml", "r") as stream:
try: try:
data_yaml = yaml.safe_load(stream) data_yaml = yaml.safe_load(stream)
pkgs_json.update({"cur_version":""}) pkgs_json.update({"cur_version":""})
@ -265,16 +174,12 @@ class UpdateList():
group_json.update({ug:pkgs_json}) group_json.update({ug:pkgs_json})
single_json = {} single_json = {}
for us in self.upgrade_meta.single_pkgs: for us in self.update_meta.get_singles():
pkg_cache = cache[us] pkg_cache = cache[us]
pkgs_json = {} pkgs_json = {}
pkgs_json.update({"cur_version":getattr(pkg_cache.installed, "version", '')}) pkgs_json.update({"cur_version":getattr(pkg_cache.installed, "version", '')})
if pkg in split_adjust_pkgs: pkgs_json.update({"new_version":getattr(pkg_cache.candidate, "version", '')})
version_adjust = _adjust_pkgs[split_adjust_pkgs.index(pkg)].split("=")[1]
pkgs_json.update({"new_version":version_adjust})
else:
pkgs_json.update({"new_version":getattr(pkg_cache.candidate, "version", '')})
pkgs_json.update({"changelog":""}) pkgs_json.update({"changelog":""})
single_json.update({us:pkgs_json}) single_json.update({us:pkgs_json})
@ -356,57 +261,36 @@ class UpdateList():
def _make_groups_pkgs(self,cache,data,pkgs_upgrade = []): def _make_groups_pkgs(self,cache,data,pkgs_upgrade = []):
upgrade_pkgs_list = data['upgrade_list'] upgrade_pkgs_list = data['upgrade_list']
#检查包是否在cache中 以及是否已经安装 没有安装的话才添加到列表
new_install_list = self._check_pkg_in_cache(cache,data['install_list']) new_install_list = self._check_pkg_in_cache(cache,data['install_list'])
downgrade_raw,downgrade_pkgs = self._get_downgrade_list(cache,data)
#被降级的软件包优先级最高
for pkg in downgrade_pkgs:
if pkg in upgrade_pkgs_list:
upgrade_pkgs_list.remove(pkg)
if pkg in new_install_list:
new_install_list.remove(pkg)
if pkg in self.upgrade_meta.single_pkgs:
self.upgrade_meta.single_pkgs.remove(pkg)
#进行交集 升级列表 #进行交集 升级列表
new_upgrade_list = list(set(pkgs_upgrade) & set(upgrade_pkgs_list)) new_upgrade_list = list(set(pkgs_upgrade) & set(upgrade_pkgs_list))
#进行源过滤
new_install_list,new_upgrade_list,adjust_pkgs = self._make_fiter_origin([cache[pkg] for pkg in new_install_list + new_upgrade_list],False)
self.upgrade_meta.adjust_pkgs.extend(adjust_pkgs)
#在总升级列表中移除这些包 #在总升级列表中移除这些包
for pkg in new_upgrade_list: for pkg in new_upgrade_list:
pkgs_upgrade.remove(pkg) pkgs_upgrade.remove(pkg)
downgrade_pkg,adjust_pkgs = self._make_downgrade(cache,downgrade_raw)
self.upgrade_meta.adjust_pkgs.extend(adjust_pkgs)
new_upgrade_list.extend(downgrade_pkg)
#单包的优先级最高 从组中剔除此包 #单包的优先级最高 从组中剔除此包
for pkg in self.upgrade_meta.single_pkgs: for pkg in self.update_meta.get_singles():
if pkg in new_install_list: if pkg in new_install_list:
new_install_list.remove(pkg) new_install_list.remove(pkg)
return new_install_list,new_upgrade_list return new_install_list,new_upgrade_list
def _make_groups_upgrade(self,cache,group_list,is_openkylin,pkgs_install,pkgs_upgrade,output_path,config_path):
def _make_groups_upgrade(self,cache,group_list,is_openkylin,pkgs_install,pkgs_upgrade):
upgrade_list = [] upgrade_list = []
install_list = [] install_list = []
if os.path.isdir(self.config_path) == False: if os.path.isdir(config_path) == False:
logging.warning("configPath(%s) is not exists...",self.config_path) logging.warning("configPath(%s) is not exists...",config_path)
return return
files = os.listdir(self.config_path) #获得文件夹中所有文件的名称列表 files = os.listdir(config_path) #获得文件夹中所有文件的名称列表
for ifile in files: for ifile in files:
#判是否是目录以及是否以JSON结尾
if ifile.endswith('.json'): if ifile.endswith('.json'):
#读取组JSON文件 #读取组JSON文件
with open(self.config_path+ifile,'r') as f: with open(config_path+ifile,'r') as f:
try: try:
data = json.load(f) data = json.load(f)
except Exception as exc: except Exception as exc:
@ -415,7 +299,7 @@ class UpdateList():
group_name = data['package'] group_name = data['package']
#读取组的yaml 文件的changelog的信息 #读取组的yaml 文件的changelog的信息
with open(self.config_path + group_name + ".yaml", "r") as stream: with open(config_path + group_name + ".yaml", "r") as stream:
try: try:
data_yaml = yaml.safe_load(stream) data_yaml = yaml.safe_load(stream)
except Exception as exc: except Exception as exc:
@ -440,45 +324,53 @@ class UpdateList():
#2、生成安装的软件列表 #2、生成安装的软件列表
install_pkgs_json = self._make_pkg_info_json(cache,install_list) install_pkgs_json = self._make_pkg_info_json(cache,install_list)
#输出JSON配置文件 #输出JSON配置文件
self._make_group_output_json(data,data_yaml,upgrade_pkgs_json,install_pkgs_json) self._make_group_output_json(data,data_yaml,upgrade_pkgs_json,install_pkgs_json,output_path)
#保存分组版本号,好像没有 #保存分组版本号,好像没有
self.upgrade_meta.versoin_pkgs['groups_upgrade'].update({group_name:''}) self.update_meta.versoin_pkgs['groups_upgrade'].update({group_name:''})
#添加到字典维护的升级列表 update_script = data.setdefault("script",{})
self.upgrade_meta.upgrade_groups.append(group_name)
self.upgrade_meta.groups_pkgs.update({group_name:{"pkgs_upgrade":upgrade_list,"pkgs_install":install_list}}) steps_begin = 50
step_update = data.setdefault("step_update",{})
if step_update != {}:
for step_name in step_update:
step_data = step_update.get(step_name,{})
if step_data == {}:
continue
step_install = list(set(step_data.setdefault("install_list",[])) & set(install_list))
step_upgrade = list(set(step_data.setdefault("upgrade_list",[])) & set(upgrade_list))
need_reboot = step_data.setdefault("need_reboot",False)
if step_install == [] and step_upgrade == []:
continue
step_data["install_list"] = step_install
step_data["upgrade_list"] = step_upgrade
#进度算法
value = int((len(step_install) + len(step_upgrade))/(len(install_list) + len(upgrade_list)) * 50)
if need_reboot == True:
step_data.update({"progress_begin":steps_begin})
step_data.update({"progress_end":100})
else:
progress_end = steps_begin + value
step_data.update({"progress_begin":steps_begin})
step_data.update({"progress_end":progress_end})
steps_begin = progress_end
logging.info("Steps(%s) upgrade:%d install:%d",step_name,len(step_upgrade),len(step_install))
self.update_meta.add_steps(step_name,{step_name:step_data})
#需要重启的话 后面的阶段将不再考虑
if need_reboot == True:
break
put_data = {group_name:{"progress_begin":steps_begin,"progress_end":100,"pkgs_upgrade":upgrade_list,"pkgs_install":install_list,"script":update_script}}
self.update_meta.add_groups(group_name,put_data)
logging.info("Group(%s) upgrade:%d install:%d",group_name,len(upgrade_list),len(install_list)) logging.info("Group(%s) upgrade:%d install:%d",group_name,len(upgrade_list),len(install_list))
else: else:
pass pass
def _make_openkylin_output_json(self,upgrade_pkgs_json,install_pkgs_json):
groups_base_info = {}
output_json = {}
#FIXME: 确定输出文件的文件名 以及放置位置
output_config_name = self.OUTPUT_CONFIG_PATH + "kylin-update-desktop-system.json"
#4、添加一些基础信息
groups_base_info.update({"package":"kylin-update-desktop-system"})
groups_base_info.update({"new_version":"33797.0001"})
groups_base_info.update({"name":{"zh_CN": "系统更新","en_US": "Kylin OS"}})
groups_base_info.update({"description":{"zh_CN": "Openkylin-系统更新包","en_US": "Openkylin-System Update Package"}})
groups_base_info.update({"icon":" "})
#添加读yaml文件
groups_base_info.update({"changelog":"Openkylin-系统更新包\n"})
#5、添加升级的内容
output_json.update(groups_base_info)
output_json.update({"upgrade_list":upgrade_pkgs_json})
output_json.update({"install_list":install_pkgs_json})
#6 产生JSON文件
with open(output_config_name, 'w', encoding='utf-8') as f:
json.dump(output_json, f, ensure_ascii=False, indent=4)
logging.info("Generate Jsonfile(%s) to complete... ",output_config_name)
def _rate_application_for_package(self, application, pkg): def _rate_application_for_package(self, application, pkg):
score = 0 score = 0
desktop_file = os.path.basename(application.get_filename()) desktop_file = os.path.basename(application.get_filename())
@ -533,12 +425,12 @@ class UpdateList():
else: else:
return None return None
def _make_single_upgrade(self,cache,pkg_list): def _make_single_upgrade(self,cache,pkg_list,output_path):
for pkg in pkg_list: for pkg in pkg_list:
zh_name = '' zh_name = ''
base_info = {} base_info = {}
output_json = {} output_json = {}
output_config_name = self.OUTPUT_CONFIG_PATH + pkg + '.json' output_config_name = output_path + pkg + '.json'
pkg_cache = cache[pkg] pkg_cache = cache[pkg]
@ -576,7 +468,7 @@ class UpdateList():
logging.info("Generate Jsonfile(%s) to complete... ",output_config_name) logging.info("Generate Jsonfile(%s) to complete... ",output_config_name)
#6、保存单包版本号 #6、保存单包版本号
self.upgrade_meta.versoin_pkgs['single_upgrade'].update({pkg_cache.name:getattr(pkg_cache.installed, "version", '')}) self.update_meta.versoin_pkgs['single_upgrade'].update({pkg_cache.name:getattr(pkg_cache.installed, "version", '')})
def _make_distupgrade(self,cache): def _make_distupgrade(self,cache):
pkgs_upgrade = [] pkgs_upgrade = []
@ -597,37 +489,36 @@ class UpdateList():
return pkgs_install,pkgs_upgrade return pkgs_install,pkgs_upgrade
def update_kylin(self,cache,important_data,is_openkylin = False): def update_kylin(self,cache,important_data,is_openkylin = False):
pkgs_install = [] system_install = []
pkgs_upgrade = [] system_upgrade = []
#查找所有可升级的包 #查找所有可升级的包
if is_openkylin == True: if is_openkylin == True:
pkgs_install,pkgs_upgrade = self._make_distupgrade(cache) system_install,system_upgrade = self._make_distupgrade(cache)
else: else:
for pkg in cache: for pkg in cache:
if pkg.is_upgradable and pkg.is_installed: if pkg.is_upgradable and pkg.is_installed:
pkgs_upgrade.append(pkg.name) system_upgrade.append(pkg.name)
logging.info("System all upgradeable packages:upgrade:%d install:%d ",len(pkgs_upgrade),len(pkgs_install)) logging.info("System all upgradeable packages:upgrade:%d install:%d ",len(system_upgrade),len(system_install))
group_important_list,self.upgrade_meta.single_pkgs = self._make_important_list(cache,pkgs_upgrade,important_data) group_list,single_pkgs = self._make_important_list(cache,system_upgrade,important_data)
#清空输出的目录 #清空输出的目录
self._empty_output_dir() self._empty_output_dir(self.OUTPUT_JSON_PATH)
#important_list 为空时此次不需要升级 if not group_list and not single_pkgs:
if not group_important_list and not self.upgrade_meta.single_pkgs:
self.parent.dbusController.UpdateDetectFinished(True,[],'','')
return return
self.update_meta.add_singles(single_pkgs)
#产生单包的JSON #产生单包的JSON
self._make_single_upgrade(cache,self.upgrade_meta.single_pkgs) self._make_single_upgrade(cache,single_pkgs,self.OUTPUT_JSON_PATH)
#分组的包的JSON #分组的包的JSON
self._make_groups_upgrade(cache,group_important_list,is_openkylin,pkgs_install,pkgs_upgrade) self._make_groups_upgrade(cache,group_list,is_openkylin,\
system_install,system_upgrade,self.OUTPUT_JSON_PATH,get_config_patch())
self._make_autoupgrade_config(cache,self.upgrade_meta,self.upgrade_meta.adjust_pkgs)
self.parent.dbusController.UpdateDetectFinished(True,self.upgrade_meta.upgrade_groups + self.upgrade_meta.single_pkgs,'','')
self._make_autoupgrade_config(cache,self.OUTPUT_JSON_PATH,get_config_patch())
return return

View File

@ -1,4 +1,5 @@
#!/usr/bin/python3 #!/usr/bin/python3
# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
# DistUpgradeConfigParser.py # DistUpgradeConfigParser.py
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA # USA
@ -20,20 +21,20 @@ class UpgradeConfig(SafeConfigParser):
self.config_files.append(os.path.join(datadir, defaults_dir)) self.config_files.append(os.path.join(datadir, defaults_dir))
# our config file # our config file
self.config_files += [maincfg] self.config_files += [maincfg]
self.read(self.config_files) self.read(self.config_files, encoding='iso-8859-1')
logging.info("Initialize Upgrade ConfigFile(%s) to success",str(self.config_files)) logging.info("Initialize Upgrade ConfigFile(%s) to success",str(self.config_files))
def optionxform(self, optionstr): def optionxform(self, optionstr):
return optionstr return optionstr
def reReadConfigFiles(self): def reRead(self):
self.read(self.config_files) self.read(self.config_files, encoding='iso-8859-1')
def setValue(self, section, option, value=None,is_write = True): def setValue(self, section, option, value=None,is_write = True):
if option != 'upgradelist': if option != 'upgradelist':
logging.info("SetValue Section:%s Option:%s Value:%s",section, option, value) logging.info("SetValue Section:%s Option:%s Value:%s",section, option, value)
try: try:
self.reReadConfigFiles() self.reRead()
self.set(section, option,value) self.set(section, option,value)
except Exception as e: except Exception as e:
@ -48,7 +49,7 @@ class UpgradeConfig(SafeConfigParser):
def getWithDefault(self, section, option, default,re_read=False): def getWithDefault(self, section, option, default,re_read=False):
try: try:
if re_read == True: if re_read == True:
self.reReadConfigFiles() self.reRead()
if type(default) == bool: if type(default) == bool:
return self.getboolean(section, option) return self.getboolean(section, option)

View File

@ -9,17 +9,25 @@ __all__ = (
"ERROR_REMOVE_ESSENTIAL_PACKAGES","ERROR_NOT_DISK_SPACE","ERROR_NOT_CONFIGPKG_DEPENDENCIES","ERROR_NOT_SELFPKG_DEPENDENCIES", "ERROR_REMOVE_ESSENTIAL_PACKAGES","ERROR_NOT_DISK_SPACE","ERROR_NOT_CONFIGPKG_DEPENDENCIES","ERROR_NOT_SELFPKG_DEPENDENCIES",
"ERROR_NOT_FIX_SYSTEM","ERROR_READ_LOCAL_DEB","ERROR_LOCAL_DEB_FORMAT","ERROR_INSTALL_DEB_BASE","ERROR_LOAD_CONFIG_FAILED", "ERROR_NOT_FIX_SYSTEM","ERROR_READ_LOCAL_DEB","ERROR_LOCAL_DEB_FORMAT","ERROR_INSTALL_DEB_BASE","ERROR_LOAD_CONFIG_FAILED",
"ERROR_UPDATE_KEY_SIGNATURES","ERROR_UPDATE_NET_AUTHENTICATION","ERROR_UPDATE_NOTREAD_SOURCES","PRIORITY_UPGRADE_SUCCCESSED", "ERROR_UPDATE_KEY_SIGNATURES","ERROR_UPDATE_NET_AUTHENTICATION","ERROR_UPDATE_NOTREAD_SOURCES","PRIORITY_UPGRADE_SUCCCESSED",
"ERROR_UPDATE_INVALID_TIME", "ERROR_UPDATE_INVALID_TIME","ERROR_UPDATE_SOURCE_TIMEOUT","ERROR_PROGRAM_EXCEPTION","ERROR_RUN_SCRIPTS_FAILED",
"get_error_description_from_enum", "get_error_string_from_enum", "get_source_name_from_enum", "get_caller_from_enum") "get_error_description_from_enum", "get_error_string_from_enum", "get_source_name_from_enum", "get_caller_from_enum",
"get_error_code_from_enum","get_policykit_authority_action_enum"
)
import gettext import gettext
gettext.bindtextdomain('kylin-system-updater', '/usr/share/locale') gettext.bindtextdomain('kylin-system-updater', '/usr/share/locale')
gettext.textdomain('kylin-system-updater') gettext.textdomain('kylin-system-updater')
_ = gettext.gettext _ = gettext.gettext
from aptdaemon.enums import (
ERROR_REPO_DOWNLOAD_FAILED
)
PRIORITY_UPGRADE_SUCCCESSED = "priority-upgrade-successed" PRIORITY_UPGRADE_SUCCCESSED = "priority-upgrade-successed"
ERROR_PROGRAM_EXCEPTION = "error_program_exception"
#apt update阶段出现的错误解析 #apt update阶段出现的错误解析
ERROR_UPDATE_DEFAULT_FAILED = "error-update-default-failed" ERROR_UPDATE_DEFAULT_FAILED = "error-update-default-failed"
ERROR_UPDATE_KEY_SIGNATURES = "The following signatures" ERROR_UPDATE_KEY_SIGNATURES = "The following signatures"
@ -28,6 +36,7 @@ ERROR_UPDATE_NOTREAD_SOURCES = "The list of sources could not be read"
ERROR_UPDATE_INVALID_TIME = "(invalid for another" ERROR_UPDATE_INVALID_TIME = "(invalid for another"
ERROR_UPDATE_SOURCE_FAILED = "error-update-source-failed" ERROR_UPDATE_SOURCE_FAILED = "error-update-source-failed"
ERROR_UPDATE_SOURCE_TIMEOUT = "error-update-source-timeout"
ERROR_NETWORK_FAILED = "error-network-failed" ERROR_NETWORK_FAILED = "error-network-failed"
ERROR_NOT_GROUPS_CONFIG = "error-not-groups-config" ERROR_NOT_GROUPS_CONFIG = "error-not-groups-config"
ERROR_NOT_CONFIGPKG_DEPENDENCIES = "error-not-configpkg-dependencies" ERROR_NOT_CONFIGPKG_DEPENDENCIES = "error-not-configpkg-dependencies"
@ -44,6 +53,7 @@ ERROR_READ_IMPORTANTLIST_FAILED = "error-read-importantlist-failed"
ERROR_RESOLVER_FAILED = "error-resolver-failed" ERROR_RESOLVER_FAILED = "error-resolver-failed"
ERROR_NOT_UPGRADE_PACKAGES = "error-not-upgrade-packages" ERROR_NOT_UPGRADE_PACKAGES = "error-not-upgrade-packages"
ERROR_REMOVE_ESSENTIAL_PACKAGES = "error-remove-essential-packages" ERROR_REMOVE_ESSENTIAL_PACKAGES = "error-remove-essential-packages"
ERROR_RUN_SCRIPTS_FAILED = "error-run-scripts-failed"
ERROR_NOT_DISK_SPACE = "error-not-disk-space" ERROR_NOT_DISK_SPACE = "error-not-disk-space"
ERROR_READ_LOCAL_DEB = "error-read-local-deb" ERROR_READ_LOCAL_DEB = "error-read-local-deb"
ERROR_LOCAL_DEB_FORMAT = "error-local-deb-format" ERROR_LOCAL_DEB_FORMAT = "error-local-deb-format"
@ -55,6 +65,7 @@ _STRINGS_ERROR = {
#update #update
ERROR_UPDATE_DEFAULT_FAILED: _("Check for update exceptions!"), ERROR_UPDATE_DEFAULT_FAILED: _("Check for update exceptions!"),
ERROR_UPDATE_SOURCE_FAILED: _("Check for update exceptions!"), ERROR_UPDATE_SOURCE_FAILED: _("Check for update exceptions!"),
ERROR_UPDATE_SOURCE_TIMEOUT: _("Check for update exceptions!"),
ERROR_NETWORK_FAILED: _("Network anomaly, can't check for updates!"), ERROR_NETWORK_FAILED: _("Network anomaly, can't check for updates!"),
ERROR_UPDATE_KEY_SIGNATURES: _("Check for update exceptions!"), ERROR_UPDATE_KEY_SIGNATURES: _("Check for update exceptions!"),
ERROR_READ_IMPORTANTLIST_FAILED: _("Check for update exceptions!"), ERROR_READ_IMPORTANTLIST_FAILED: _("Check for update exceptions!"),
@ -62,6 +73,7 @@ _STRINGS_ERROR = {
ERROR_NOT_INIT_PACKAGESINFIO: _("Check for update exceptions!"), ERROR_NOT_INIT_PACKAGESINFIO: _("Check for update exceptions!"),
ERROR_NOT_FIX_SYSTEM: _("Check for update exceptions!"), ERROR_NOT_FIX_SYSTEM: _("Check for update exceptions!"),
ERROR_LOAD_CONFIG_FAILED: _("Check for update exceptions!"), ERROR_LOAD_CONFIG_FAILED: _("Check for update exceptions!"),
ERROR_PROGRAM_EXCEPTION: _("Check for update exceptions!"),
#优先升级 #优先升级
ERROR_NOT_GROUPS_CONFIG: _("Upgrade configuration acquisition exception."), ERROR_NOT_GROUPS_CONFIG: _("Upgrade configuration acquisition exception."),
@ -72,14 +84,17 @@ _STRINGS_ERROR = {
ERROR_RESOLVER_FAILED: _("Could not calculate the upgrade"), ERROR_RESOLVER_FAILED: _("Could not calculate the upgrade"),
ERROR_NOT_UPGRADE_PACKAGES: _("There is an exception in the update package."), ERROR_NOT_UPGRADE_PACKAGES: _("There is an exception in the update package."),
ERROR_REMOVE_ESSENTIAL_PACKAGES: _("There is an exception in the update package."), ERROR_REMOVE_ESSENTIAL_PACKAGES: _("There is an exception in the update package."),
ERROR_RUN_SCRIPTS_FAILED: _("There is an exception in the update package."),
ERROR_NOT_DISK_SPACE: _("Disk space is insufficient, please clean the disk and then upgrade"), ERROR_NOT_DISK_SPACE: _("Disk space is insufficient, please clean the disk and then upgrade"),
ERROR_READ_LOCAL_DEB:_(" "), ERROR_READ_LOCAL_DEB:_(" "),
ERROR_LOCAL_DEB_FORMAT:_(" "), ERROR_LOCAL_DEB_FORMAT:_(" "),
ERROR_INSTALL_DEB_BASE:_(" ")} ERROR_INSTALL_DEB_BASE:_(" ")}
_DESCS_ERROR = { _DESCS_ERROR = {
ERROR_PROGRAM_EXCEPTION: _("Program exception, please contact the administrator to solve."),
#update #update
ERROR_UPDATE_SOURCE_FAILED: _("Unable to access the source management server"), ERROR_UPDATE_SOURCE_FAILED: _("Unable to access the source management server, please try again later"),
ERROR_UPDATE_SOURCE_TIMEOUT: _("Access to the source management server timed out, please try again later"),
ERROR_NETWORK_FAILED: _("Please check your network connection and retry."), ERROR_NETWORK_FAILED: _("Please check your network connection and retry."),
ERROR_UPDATE_KEY_SIGNATURES: _("Check your source public key signature"), ERROR_UPDATE_KEY_SIGNATURES: _("Check your source public key signature"),
ERROR_UPDATE_NOTREAD_SOURCES: _("Please check your source list and retry."), ERROR_UPDATE_NOTREAD_SOURCES: _("Please check your source list and retry."),
@ -102,12 +117,45 @@ _DESCS_ERROR = {
ERROR_RESOLVER_FAILED: _("nothing"), ERROR_RESOLVER_FAILED: _("nothing"),
ERROR_NOT_UPGRADE_PACKAGES: _("This update cannot detect the upgradeable package."), ERROR_NOT_UPGRADE_PACKAGES: _("This update cannot detect the upgradeable package."),
ERROR_REMOVE_ESSENTIAL_PACKAGES: _("You request the removal of a system-essential package."), ERROR_REMOVE_ESSENTIAL_PACKAGES: _("You request the removal of a system-essential package."),
ERROR_RUN_SCRIPTS_FAILED:_("Exceptions to running the check script."),
ERROR_NOT_DISK_SPACE: _("test"), ERROR_NOT_DISK_SPACE: _("test"),
ERROR_READ_LOCAL_DEB:_("Deb format exception, read local deb file error."), ERROR_READ_LOCAL_DEB:_("Deb format exception, read local deb file error."),
ERROR_LOCAL_DEB_FORMAT:_("Deb format exception, failed to parse package file."), ERROR_LOCAL_DEB_FORMAT:_("Deb format exception, failed to parse package file."),
ERROR_INSTALL_DEB_BASE:_("Install deb error.") ERROR_INSTALL_DEB_BASE:_("Install deb error.")
} }
_CODE_ERROR = {
ERROR_PROGRAM_EXCEPTION: "#0000",
#update
ERROR_UPDATE_SOURCE_FAILED: "#0100",
ERROR_UPDATE_SOURCE_TIMEOUT: "#0101",
ERROR_NETWORK_FAILED: "#0102",
ERROR_UPDATE_KEY_SIGNATURES: "#0103",
ERROR_UPDATE_NOTREAD_SOURCES: "#0104",
ERROR_UPDATE_INVALID_TIME: "#0105",
ERROR_UPDATE_NET_AUTHENTICATION: "#0106",
ERROR_NOT_GROUPS_CONFIG: "#0107",
ERROR_NOT_INIT_PACKAGESINFIO: "#0108",
ERROR_SOFTWARE_INDEX_RROKEN: "#0109",
ERROR_READ_IMPORTANTLIST_FAILED: "#0110",
ERROR_NOT_CONFIGPKG_DEPENDENCIES: "#0111",
ERROR_NOT_SELFPKG_DEPENDENCIES: "#0112",
ERROR_LOAD_CONFIG_FAILED: "#0113",
ERROR_NOT_FIX_SYSTEM: "#0114",
ERROR_REPO_DOWNLOAD_FAILED: "#0115",
#install
ERROR_RESOLVER_FAILED: "#0200",
ERROR_NOT_UPGRADE_PACKAGES: "#0201",
ERROR_REMOVE_ESSENTIAL_PACKAGES: "#0202",
ERROR_RUN_SCRIPTS_FAILED: "#0203",
ERROR_NOT_DISK_SPACE: "#0204",
ERROR_READ_LOCAL_DEB: "#0205",
ERROR_LOCAL_DEB_FORMAT: "#0206",
ERROR_INSTALL_DEB_BASE: "#0207"
}
#UPGRADE MONITOR STATUS #UPGRADE MONITOR STATUS
MONIT_DETECT = "step-updatedetect" MONIT_DETECT = "step-updatedetect"
MONIT_DEPRESOLUT = "step-depresolution" MONIT_DEPRESOLUT = "step-depresolution"
@ -130,6 +178,13 @@ CALLER = {
'kylin-software-center':"Kylin Software Center", 'kylin-software-center':"Kylin Software Center",
} }
PolicyKit_Authority_Action = {
'kylin-installer':"cn.kylin.installer.action",
'kylin-uninstaller':"cn.kylin.uninstaller.action",
'kylin-software-center':"cn.kylin.software.center.action",
'kylin-system-updater':"cn.kylinos.KylinSystemUpdater.action",
}
def get_error_description_from_enum(enum): def get_error_description_from_enum(enum):
"""Get a long description of an error. """Get a long description of an error.
@ -141,6 +196,16 @@ def get_error_description_from_enum(enum):
except KeyError: except KeyError:
return None return None
def get_error_code_from_enum(enum):
"""Get a long description of an error.
:param enum: The transaction error enum, e.g. :data:`ERROR_NO_LOCK`.
:returns: The description string.
"""
try:
return _CODE_ERROR[enum]
except KeyError:
return enum
def get_error_string_from_enum(enum): def get_error_string_from_enum(enum):
"""Get a short description of an error. """Get a short description of an error.
@ -166,4 +231,10 @@ def get_caller_from_enum(enum):
except KeyError: except KeyError:
return _("Kylin System Updater") return _("Kylin System Updater")
def get_policykit_authority_action_enum(enum):
try:
return PolicyKit_Authority_Action[enum]
except KeyError:
return "cn.kylinos.KylinSystemUpdater.action" #默认配置
# vim:ts=4:sw=4:et # vim:ts=4:sw=4:et

View File

@ -57,6 +57,7 @@ import psutil
import ctypes import ctypes
from ctypes import * from ctypes import *
import struct import struct
from SystemUpdater.Core.enums import get_policykit_authority_action_enum
# 禁止关机锁文件路径 # 禁止关机锁文件路径
VERIFY_SO = "libkylin_signtool.so" VERIFY_SO = "libkylin_signtool.so"
@ -731,18 +732,6 @@ def deb_verify(deb_path, _isinstall = False):
_deb_path = str(deb_path) _deb_path = str(deb_path)
try: try:
# # 加载验证签名库 , 验签接口暂时无法调用 # # 加载验证签名库 , 验签接口暂时无法调用
# args = ["dpkg-architecture", "-qDEB_TARGET_MULTIARCH"]
# ret = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True)
# verifyso_path = os.path.join("/usr/lib/",str(ret.stdout).strip(),VERIFY_SO)
# logging.info("Load verify interface:%s.",verifyso_path)
# verifyso = ctypes.CDLL(verifyso_path)
# #环境初始化
# ret = verifyso.SOF_Initialize(ctx_obj)
# if (ret) :
# logging.info("SOF_InitializeEx error!")
# return 2
# if os.path.isfile(_deb_path):
# ret = verifyso.BJCA_dodebverify(None, bytes(_deb_path, encoding='utf8'), _isinstall)
if not os.path.isfile("/usr/bin/kylinsigntool"): if not os.path.isfile("/usr/bin/kylinsigntool"):
logging.error("SOF_InitializeEx error!") logging.error("SOF_InitializeEx error!")
return 1 return 1
@ -750,42 +739,46 @@ def deb_verify(deb_path, _isinstall = False):
ret = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True) ret = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True)
if "Signature Verified failed" in str(ret.stdout).strip() or "签名验证失败" in str(ret.stdout).strip(): if "Signature Verified failed" in str(ret.stdout).strip() or "签名验证失败" in str(ret.stdout).strip():
logging.info("Signature Verified failed!") logging.info("Signature Verified failed!")
return 2
elif "Signature Verified Ok" in str(ret.stdout).strip() or "签名验证成功" in str(ret.stdout).strip(): elif "Signature Verified Ok" in str(ret.stdout).strip() or "签名验证成功" in str(ret.stdout).strip():
logging.info("Signature Verified Ok!") logging.info("Signature Verified Ok!")
return 0 return 0
else:
logging.error("Signature Verified failed:%s.",ret)
return 2
except Exception as e: except Exception as e:
logging.error(e) logging.error(e)
return 3 return 3
def PolicyKit_Authority(details = '', sender = None): def PolicyKit_Authority(details = '', sender = None, InstPolicy = False, source=''):
_allow_kylinsign = False _allow_kylinsign = False
_verify_kylinsign = False _verify_kylinsign = False
try: try:
#获取未知来源应用安装策略Unknown sources apply installation policies if InstPolicy:
inst_policies_path = "/etc/dpkg/dpkg.cfg" #获取未知来源应用安装策略Unknown sources apply installation policies
if os.path.isfile(inst_policies_path): inst_policies_path = "/etc/dpkg/dpkg.cfg"
with open(inst_policies_path, "r") as f: if os.path.isfile(inst_policies_path):
lines = f.readlines() with open(inst_policies_path, "r") as f:
for line in lines: lines = f.readlines()
if "allow-kylinsign" in line: for line in lines:
_allow_kylinsign = True if "allow-kylinsign" in line:
if "verify-kylinsign" in line: _allow_kylinsign = True
_verify_kylinsign = True if "verify-kylinsign" in line:
if _allow_kylinsign == True and _verify_kylinsign == False: #策略: 阻止 _verify_kylinsign = True
logging.debug("unknown sources apply installation policies: deter") if _allow_kylinsign == True and _verify_kylinsign == False: #策略: 阻止
return False,_("The package is unsigned, refuses to install.") logging.debug("unknown sources apply installation policies: deter")
elif _allow_kylinsign == True and _verify_kylinsign == True: #策略: 警告 return False,_("The package is unsigned, refuses to install.")
logging.debug("unknown sources apply installation policies: warning") elif _allow_kylinsign == True and _verify_kylinsign == True: #策略: 警告
elif _allow_kylinsign == False and _verify_kylinsign == False: #策略: 关闭 logging.debug("unknown sources apply installation policies: warning")
logging.debug("unknown sources apply installation policies: close") elif _allow_kylinsign == False and _verify_kylinsign == False: #策略: 关闭
else: logging.debug("unknown sources apply installation policies: close")
logging.warning("Unknown sources apply installation policies get failed.") else:
logging.warning("Unknown sources apply installation policies get failed.")
#用户鉴权 #用户鉴权
logging.debug("Authentication via PolicyKit .")
details = {'polkit.message':details} details = {'polkit.message':details}
cancel_id = '' cancel_id = ''
action = "cn.kylinos.KylinSystemUpdater.action" action = get_policykit_authority_action_enum(source)
kit = dbus.SystemBus().get_object('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority') kit = dbus.SystemBus().get_object('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority')
kit = dbus.Interface(kit, 'org.freedesktop.PolicyKit1.Authority') kit = dbus.Interface(kit, 'org.freedesktop.PolicyKit1.Authority')
(granted, notused , details) = kit.CheckAuthorization( (granted, notused , details) = kit.CheckAuthorization(

View File

@ -22,12 +22,15 @@ from .Core.enums import *
from .Core.MyCache import MyCache from .Core.MyCache import MyCache
from .UpdateManagerDbus import UpdateManagerDbusController,UpdateManagerDbusControllerUtils,UPDATER_DBUS_INTERFACE,UPDATER_DBUS_PATH,UPDATER_DBUS_SERVICE from .UpdateManagerDbus import UpdateManagerDbusController,UpdateManagerDbusControllerUtils,UPDATER_DBUS_INTERFACE,UPDATER_DBUS_PATH,UPDATER_DBUS_SERVICE
from .Core.UpdateList import UpdateList from .Core.UpdateList import UpdateList
from .Core.PluginManager import *
from .backend import InstallBackend,get_backend from .backend import InstallBackend,get_backend
from .Core.Database import Sqlite3Server from .Core.Database import Sqlite3Server
from .Core.loop import mainloop from .Core.loop import mainloop
from .Core.DataAcquisition import UpdateMsgCollector from .Core.DataAcquisition import UpdateMsgCollector
from SystemUpdater.Core.LocalUpgradeData import LocalUpgradeDataList
from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
from SystemUpdater.Core.JsonConfigParser import JsonConfig as json_config
from SystemUpdater.Core.utils import kill_process from SystemUpdater.Core.utils import kill_process
from SystemUpdater.Core.DpkgInstallProgress import LogInstallProgress from SystemUpdater.Core.DpkgInstallProgress import LogInstallProgress
from SystemUpdater.Core.utils import deb_verify,PolicyKit_Authority,get_proc_from_dbus_name,whether_to_quit_uu,get_dist from SystemUpdater.Core.utils import deb_verify,PolicyKit_Authority,get_proc_from_dbus_name,whether_to_quit_uu,get_dist
@ -61,52 +64,18 @@ class UpdateManager():
self.collector = UpdateMsgCollector(self) self.collector = UpdateMsgCollector(self)
#连接数据库 #连接数据库
self.sqlite3_server = Sqlite3Server(self) self.sqlite3_server = Sqlite3Server(self)
self.pm_class = pluginManagerClass()
self.simulate_mode = SimulateTerminal() self.simulate_mode = SimulateTerminal()
self.install_mode = UpdateInstallMode(self) self.install_mode = UpdateInstallMode(self)
self.apt_p2p_config = AptP2pConfigManager() self.apt_p2p_config = AptP2pConfigManager()
self._reload_options_config() self.main_meta = LocalUpgradeDataList()
json_config()
self._refresh_cache_only() self._refresh_cache_only()
except Exception as e: except Exception as e:
logging.error(e) logging.error(e)
traceback.print_exc() traceback.print_exc()
def _reload_options_config(self):
#添加默认保留旧配置
apt_pkg.config["DPkg::Options::"] = "--force-confold"
options_new = list(set(apt_pkg.config.value_list("DPkg::Options")))
for option in ("--force-confnew","--force-confdef"):
if option in options_new:
options_new.remove(option)
#清除所有配置重新加载
apt_pkg.config.clear("DPkg::Options")
for option in options_new:
apt_pkg.config["DPkg::Options::"] = option
#去除安装推荐和建议的软件包
if apt_pkg.config.find_b("APT::Install-Recommends",False) == True:
apt_pkg.config.clear("APT::Install-Recommends")
if apt_pkg.config.find_b("APT::Install-Suggests",False) == True:
apt_pkg.config.clear("APT::Install-Suggests")
def check_frontend_pkg(self):
#控制面板前端包的检查升级
if self.FRONTEND_PKG_NAME in self.cache:
self_pkg = self.cache[self.FRONTEND_PKG_NAME]
if not self_pkg.is_installed:
logging.info("Check: Frontend(%s) start new installing...",self.FRONTEND_PKG_NAME)
self_pkg.mark_install()
self.start_install(InstallBackend.MODE_INSTALL_SINGLE,True)
else:
#没有在cache中就认为不需要升级
logging.error("Check: Frontend(%s) The upgrade package is not in Cache...",self.FRONTEND_PKG_NAME)
#检查是否需要重新启动aptdeamon 目前需要重启的有限速功能
def check_conifg_aptdeamon(self):
if self.init_config_aptdeamon == True:
self.init_config_aptdeamon = False
self.dbusController.set_aptdeamon_environ("init","config")
def run(self): def run(self):
"""Start the daemon and listen for calls.""" """Start the daemon and listen for calls."""
logging.info("Waiting for calls...") logging.info("Waiting for calls...")
@ -131,30 +100,39 @@ class UpdateManager():
fix_backend.start() fix_backend.start()
#进行升级的操作 #进行升级的操作
def start_install(self,upgrade_mode,not_resolver = False,upgrade_content = []): def start_install(self,upgrade_mode = InstallBackend.MODE_DEFAULT_STATUS,not_resolver = False,push_content = []):
try: try:
if self.install_mode.shutdown_mode() == True and upgrade_mode != InstallBackend.MODE_INSTALL_SINGLE: if self.install_mode.shutdown_mode() == True and upgrade_mode != InstallBackend.MODE_INSTALL_SINGLE:
#部分升级的方式 计算的时候 补上上次更新的内容一起计算 #部分升级的方式 计算的时候 补上上次更新的内容一起计算
if upgrade_mode == InstallBackend.MODE_INSTALL_PARTIAL: if upgrade_mode == InstallBackend.MODE_INSTALL_PARTIAL:
upgrade_content += self.install_mode.tmp_content push_content += self.install_mode.tmp_content
if not_resolver == True: if not_resolver == True:
kill_process(self.RUN_UNATTENDED_UPGRADE) # if whether_to_quit_uu():
#未下载的阶段 # kill_process(self.RUN_UNATTENDED_UPGRADE)
self.check_config_aptdeamon()
install_backend = get_backend(self, InstallBackend.ACTION_DOWNLOADONLY,upgrade_mode) install_backend = get_backend(self, InstallBackend.ACTION_DOWNLOADONLY,upgrade_mode)
install_backend.start(upgrade_content) install_backend.start(push_content)
else: else:
resolver_backend = get_backend(self, InstallBackend.ACTION_CHECK_RESOLVER,upgrade_mode) resolver_backend = get_backend(self, InstallBackend.ACTION_CHECK_RESOLVER,upgrade_mode)
resolver_backend.start(upgrade_content) resolver_backend.start_resolver(push_content)
else: else:
if self.main_meta.is_steps(push_content) == True and \
upgrade_mode != InstallBackend.MODE_INSTALL_SYSTEM:
upgrade_mode = InstallBackend.MODE_INSTALL_STEP
if not_resolver == True: if not_resolver == True:
if whether_to_quit_uu(): # if whether_to_quit_uu():
kill_process(self.RUN_UNATTENDED_UPGRADE) # kill_process(self.RUN_UNATTENDED_UPGRADE)
self.check_config_aptdeamon()
install_backend = get_backend(self, InstallBackend.ACTION_INSTALL,upgrade_mode) install_backend = get_backend(self, InstallBackend.ACTION_INSTALL,upgrade_mode)
install_backend.start(upgrade_content) install_backend.start(push_content)
else: else:
resolver_backend = get_backend(self, InstallBackend.ACTION_CHECK_RESOLVER,upgrade_mode) resolver_backend = get_backend(self, InstallBackend.ACTION_CHECK_RESOLVER,upgrade_mode)
resolver_backend.start(upgrade_content) resolver_backend.start_resolver(push_content)
except Exception as e: except Exception as e:
logging.error(e) logging.error(e)
@ -162,12 +140,8 @@ class UpdateManager():
def start_update(self,update_mode = InstallBackend.MODE_UPDATE_ALL): def start_update(self,update_mode = InstallBackend.MODE_UPDATE_ALL):
try: try:
#更新前的准备 #更新前的准备
self.configs_cover.reReadConfigFiles() # self.install_mode.reset_shutdown_mode()
self.retry_limit = self.RETRY_LIMIT_NUM
self.install_mode.reset_shutdown_mode()
#检查 光盘源
self.install_mode.check_source() self.install_mode.check_source()
if self.install_mode.check_network() == True: if self.install_mode.check_network() == True:
@ -185,12 +159,16 @@ class UpdateManager():
self.start_update_backend(update_mode = update_mode) self.start_update_backend(update_mode = update_mode)
except UpdateBaseError as excep: except UpdateBaseError as excep:
self.dbusController.InstallDetectStatus(False,get_error_code_from_enum(excep.code))
self.dbusController.UpdateDetectFinished(False,[''],excep.header,excep.desc) self.dbusController.UpdateDetectFinished(False,[''],excep.header,excep.desc)
except UpdateProgressExit: except UpdateProgressExit:
pass pass
except Exception as e: except Exception as e:
logging.error(e) logging.error(e)
traceback.print_exc() traceback.print_exc()
self.dbusController.InstallDetectStatus(False,get_error_code_from_enum(ERROR_PROGRAM_EXCEPTION))
self.dbusController.UpdateDetectFinished(False,[''],get_error_string_from_enum(ERROR_PROGRAM_EXCEPTION),\
get_error_description_from_enum(ERROR_PROGRAM_EXCEPTION))
def start_update_backend(self,update_mode = InstallBackend.MODE_UPDATE_ALL): def start_update_backend(self,update_mode = InstallBackend.MODE_UPDATE_ALL):
#调用aptdeamon进行update #调用aptdeamon进行update
@ -199,39 +177,47 @@ class UpdateManager():
def start_available(self): def start_available(self):
try: try:
self.configs_cover.reRead()
self.retry_limit = self.RETRY_LIMIT_NUM
json_config().read()
self.refresh_cache() self.refresh_cache()
self.main_meta.refresh()
self.update_list = UpdateList(self) self.update_list = UpdateList(self)
#1、 检查出现安装过程异常重启 出现的话 进行异常修复
if self.configs_uncover.getWithDefault("SystemStatus", "abnormal_reboot", False) == True: if self.configs_uncover.getWithDefault("SystemStatus", "abnormal_reboot", False) == True:
self.configs_uncover.setValue("SystemStatus","abnormal_reboot",str(False),True) self.configs_uncover.setValue("SystemStatus","abnormal_reboot",str(False),True)
logging.warning("start fix Abnormal Reboot broken pkgs...") logging.warning("start fix Abnormal Reboot broken pkgs...")
self.start_fix_broken() self.start_fix_broken()
return return
#检查当前系统的状态 是否存在系统为破损状态 导致出现异常
self._check_system_broken(self.cache) self._check_system_broken(self.cache)
#检查优先自我升级 self._check_config_upgrade(self.cache)
self._check_self_upgrade(self.cache) self._check_self_upgrade(self.cache)
self.update_list.update_kylin(self.cache,self.install_mode.get_important_data(),self.install_mode.is_openkylin_desktop()) self.update_list.update_kylin(self.cache,self.install_mode.get_important_data(),self.install_mode.is_openkylin_desktop())
if self.cache != None and self.cache.get_changes(): self.dbusController.UpdateDetectFinished(True,self.main_meta.get_push(),'','')
self.cache.clear()
except UpdateBaseError as excep: except UpdateBaseError as excep:
self.dbusController.InstallDetectStatus(False,get_error_code_from_enum(excep.code))
self.dbusController.UpdateDetectFinished(False,[''],excep.header,excep.desc) self.dbusController.UpdateDetectFinished(False,[''],excep.header,excep.desc)
except UpdateProgressExit as excep: except UpdateProgressExit as excep:
pass pass
except Exception as e: except Exception as e:
logging.error(e) logging.error(e)
traceback.print_exc() traceback.print_exc()
self.dbusController.UpdateDetectFinished(False,[''],get_error_string_from_enum(ERROR_PROGRAM_EXCEPTION),\
get_error_description_from_enum(ERROR_PROGRAM_EXCEPTION))
def refresh_cache(self): def refresh_cache(self):
try: try:
#第一次进入 之后update不进入
if self.cache is None: if self.cache is None:
self.cache = MyCache(None) self.cache = MyCache(None)
else: else:
@ -245,44 +231,17 @@ class UpdateManager():
raise UpdateBaseError(ERROR_NOT_INIT_PACKAGESINFIO) raise UpdateBaseError(ERROR_NOT_INIT_PACKAGESINFIO)
def _refresh_cache_only(self): def _refresh_cache_only(self):
#第一次进入 之后update不进入 self._reload_options_config()
if self.cache is None: if self.cache is None:
self.cache = MyCache(None) self.cache = MyCache(None)
else: else:
self.cache.open(None) self.cache.open(None)
self.cache._initDepCache() self.cache._initDepCache()
def _check_self_upgrade(self,cache): def _check_config_upgrade(self,cache):
need_upgrade = False need_upgrade = False
self_upgrade = [] self_upgrade = []
important_list = self.install_mode.get_important_data()
for pkg_name in [self.BACKEND_PKG_NAME,self.APTD_PKG_NAME,self.FRONTEND_PKG_NAME]:
if pkg_name in cache:
self_pkg = cache[pkg_name]
if self_pkg.is_installed:
if self_pkg.is_upgradable:
logging.info("Check: (%s) will upgrading From %s to %s...",pkg_name,\
self_pkg.installed.source_version,self_pkg.candidate.source_version)
if pkg_name in important_list:
try:
logging.info("Check: (%s) start upgrading From %s to %s...",pkg_name,\
self_pkg.installed.source_version,self_pkg.candidate.source_version)
self_pkg.mark_install(True,False,True)
self_upgrade.append(pkg_name)
need_upgrade = True
except SystemError:
self.simulate_mode.thread_install([pkg_name])
logging.error("Check: mark %s to upgrade Failed...",pkg_name)
raise UpdateBaseError(ERROR_NOT_SELFPKG_DEPENDENCIES)
else:
logging.info("Check: (%s:%s) No need to upgrade and duo to not pust...",pkg_name,self_pkg.installed.source_version)
else:
logging.info("Check: (%s:%s) No need to upgrade...",pkg_name,self_pkg.installed.source_version)
else:
logging.info("Check: (%s) Not to be installed...",pkg_name)
else:
logging.error("Check: (%s) The upgrade package is not in Cache...",pkg_name)
#config包 #config包
for pkg_name in [self.GROUPS_PKG_NAME]: for pkg_name in [self.GROUPS_PKG_NAME]:
@ -318,16 +277,54 @@ class UpdateManager():
if need_upgrade == True: if need_upgrade == True:
self.dbusController.UpdateDetectStatusChanged(95,_("Priority Upgrade Package being updated")) self.dbusController.UpdateDetectStatusChanged(95,_("Priority Upgrade Package being updated"))
self.start_install(InstallBackend.MODE_INSTALL_SINGLE,True,upgrade_content=self_upgrade) self.start_install(InstallBackend.MODE_INSTALL_SINGLE,True,push_content=self_upgrade)
raise UpdateProgressExit()
def _check_self_upgrade(self,cache):
need_upgrade = False
self_upgrade = []
channel_config = json_config().getWithDefault("update_channel_upgrade",default = None)
if channel_config == None:
logging.warning("Json: update_channel_upgrade item is None...")
upgrade_list = [self.BACKEND_PKG_NAME,self.APTD_PKG_NAME,self.FRONTEND_PKG_NAME]
else:
upgrade_list = channel_config.get("upgrade_list",[self.BACKEND_PKG_NAME,self.APTD_PKG_NAME,self.FRONTEND_PKG_NAME])
for pkg_name in upgrade_list:
if pkg_name in cache:
self_pkg = cache[pkg_name]
if self_pkg.is_installed:
if self_pkg.is_upgradable:
logging.info("Check: (%s) will upgrading From %s to %s...",pkg_name,\
self_pkg.installed.source_version,self_pkg.candidate.source_version)
try:
logging.info("Check: (%s) start upgrading From %s to %s...",pkg_name,\
self_pkg.installed.source_version,self_pkg.candidate.source_version)
self_pkg.mark_install(True,False,True)
self_upgrade.append(pkg_name)
need_upgrade = True
except SystemError:
self.simulate_mode.thread_install([pkg_name])
logging.error("Check: mark %s to upgrade Failed...",pkg_name)
raise UpdateBaseError(ERROR_NOT_SELFPKG_DEPENDENCIES)
else:
logging.info("Check: (%s:%s) No need to upgrade...",pkg_name,self_pkg.installed.source_version)
else:
logging.info("Check: (%s) Not to be installed...",pkg_name)
else:
logging.error("Check: (%s) The upgrade package is not in Cache...",pkg_name)
if need_upgrade == True:
self.dbusController.UpdateDetectStatusChanged(95,_("Priority Upgrade Package being updated"))
self.start_install(InstallBackend.MODE_INSTALL_SINGLE,True,push_content=self_upgrade)
raise UpdateProgressExit() raise UpdateProgressExit()
def _check_system_broken(self,cache): def _check_system_broken(self,cache):
if cache.get_changes(): if cache.get_changes():
cache.clear() cache.clear()
#获取出现破损状态包的数量
if cache._depcache.broken_count or cache._depcache.del_count > 0 or \ if cache._depcache.broken_count or cache._depcache.del_count > 0 or \
cache._depcache.inst_count > 0: cache._depcache.inst_count > 0:
#线程获取详细的卸载软件包情况
self.simulate_mode.start_caculate(["apt-get", "install","-f","--simulate"],thread=True) self.simulate_mode.start_caculate(["apt-get", "install","-f","--simulate"],thread=True)
else: else:
logging.info("Check: System Apt Cache for Broken Successfully...") logging.info("Check: System Apt Cache for Broken Successfully...")
@ -423,7 +420,14 @@ class UpdateManager():
def start_back_upgrade(self, pkglist): def start_back_upgrade(self, pkglist):
try: try:
install_backend = get_backend(self, InstallBackend.ACTION_BACKGROUND_UPGRADE) install_backend = get_backend(self, InstallBackend.ACTION_BACKGROUND_UPGRADE)
install_backend.start_alone(partial_upgrade_list = pkglist) install_backend.start_alone(push_content = pkglist)
except Exception as e:
logging.error(str(e))
def start_deb_resolver(self, pkglist = []):
try:
install_backend = get_backend(self, InstallBackend.ACTION_INSTALL_DEB_RESOLVER)
install_backend.start_alone(push_content = pkglist)
except Exception as e: except Exception as e:
logging.error(str(e)) logging.error(str(e))
@ -434,6 +438,10 @@ class UpdateManager():
header = '' header = ''
desc = '' desc = ''
absolute_path, debname = os.path.split(deb_path) absolute_path, debname = os.path.split(deb_path)
self.sqlite3_server.deb_metadata.update({"current_install_debfile":deb_path})
self.sqlite3_server.deb_metadata.update({"absolute_path":absolute_path})
self.sqlite3_server.deb_metadata.update({"source":source})
self.deb_obj = {} self.deb_obj = {}
UpdateMsg = {} UpdateMsg = {}
try: try:
@ -445,10 +453,9 @@ class UpdateManager():
sender_name = get_proc_from_dbus_name(sender) sender_name = get_proc_from_dbus_name(sender)
caller = get_caller_from_enum(sender_name) caller = get_caller_from_enum(sender_name)
caller_trans = get_source_name_from_enum(sender_name) caller_trans = get_source_name_from_enum(sender_name)
if source == "kylin-software-center": if deb_verify(deb_path) != 0: #验签失败,提权
logging.info("caller : %s.",source) (status,error_string) = PolicyKit_Authority(caller_trans+_(" requires authentication to install software packages."),
else: sender,InstPolicy=True,source=source)
(status,error_string) = PolicyKit_Authority(caller_trans+_(" requires authentication to install software packages."),sender)
if not status: if not status:
self.dbusController.InstalldebFinished(False,error_string,'') self.dbusController.InstalldebFinished(False,error_string,'')
return return
@ -458,6 +465,8 @@ class UpdateManager():
UpdateMsg.update({"source":str(self.deb_obj.get("source","kylin-system-updater"))}) UpdateMsg.update({"source":str(self.deb_obj.get("source","kylin-system-updater"))})
deb_cache, ins, _isinstall = self._suit_install_mode(deb_path) deb_cache, ins, _isinstall = self._suit_install_mode(deb_path)
UpdateMsg.update({"appname":str(self.debName)}) UpdateMsg.update({"appname":str(self.debName)})
self.sqlite3_server.deb_metadata.update({"debname":str(self.debName)})
self.sqlite3_server.deb_metadata['deblist'].append(str(self.debName))
UpdateMsg.update({"new_version":str(self.debVersion)}) UpdateMsg.update({"new_version":str(self.debVersion)})
if self._is_broken > 0 or not self.cacheSatisfy or self._need_downgrade: if self._is_broken > 0 or not self.cacheSatisfy or self._need_downgrade:
# 走 dpkg 安装流程说明本地apt环境已经损坏,or dep not satisfied or need downgrade # 走 dpkg 安装流程说明本地apt环境已经损坏,or dep not satisfied or need downgrade
@ -480,7 +489,8 @@ class UpdateManager():
dep_satisfy, header, desc = self._attempt_depends(deb_cache, deb_path, _check_local_dep,_auto_satisfy, ins) dep_satisfy, header, desc = self._attempt_depends(deb_cache, deb_path, _check_local_dep,_auto_satisfy, ins)
if dep_satisfy: if dep_satisfy:
install_backend = get_backend(self, InstallBackend.ACTION_INSTALL_DEB) install_backend = get_backend(self, InstallBackend.ACTION_INSTALL_DEB)
install_backend.start_alone(partial_upgrade_list = deb_path, _is_install = _auto_satisfy, caller=caller_trans) logging.info("source name: %s.", source)
install_backend.start_alone(push_content=deb_path,_is_install=_auto_satisfy,caller=source)
else: else:
self.dbusController.InstalldebFinished(False, header, desc) self.dbusController.InstalldebFinished(False, header, desc)
except UpdateBaseError as excep: except UpdateBaseError as excep:
@ -508,12 +518,14 @@ class UpdateManager():
_success,header,desc = self._dpkg_purge_pkgs(pkgs_list) _success,header,desc = self._dpkg_purge_pkgs(pkgs_list)
if _success == True: if _success == True:
logging.info(header) logging.info(header)
# self.dbusController.PurgePackagesFinished(_success,'',desc," ".join(pkgs_list))
self.dbusController.PurgePackagesFinished(_success,'',desc) self.dbusController.PurgePackagesFinished(_success,'',desc)
else: else:
# self.dbusController.PurgePackagesFinished(_success,header,desc," ".join(pkgs_list))
self.dbusController.PurgePackagesFinished(_success,header,desc) self.dbusController.PurgePackagesFinished(_success,header,desc)
else: else:
purge_backend = get_backend(self, InstallBackend.ACTION_REMOVE_PACKAGES) purge_backend = get_backend(self, InstallBackend.ACTION_REMOVE_PACKAGES)
purge_backend.start(partial_upgrade_list = pkgs_list) purge_backend.start(push_content = pkgs_list)
deb_cache.close() deb_cache.close()
except Exception as e: except Exception as e:
@ -530,6 +542,26 @@ class UpdateManager():
success = p.returncode == 0 success = p.returncode == 0
return success,p.stdout,'' return success,p.stdout,''
def _reload_options_config(self):
apt_pkg.config["DPkg::Options::"] = "--force-confold"
options_new = list(set(apt_pkg.config.value_list("DPkg::Options")))
for option in ("--force-confnew","--force-confdef"):
if option in options_new:
options_new.remove(option)
apt_pkg.config.clear("DPkg::Options")
for option in options_new:
apt_pkg.config["DPkg::Options::"] = option
if apt_pkg.config.find_b("APT::Install-Recommends",False) == True:
apt_pkg.config.clear("APT::Install-Recommends")
if apt_pkg.config.find_b("APT::Install-Suggests",False) == True:
apt_pkg.config.clear("APT::Install-Suggests")
def check_config_aptdeamon(self):
#检查是否需要重新启动aptdeamon 目前需要重启的有限速功能
if self.init_config_aptdeamon == True:
self.init_config_aptdeamon = False
self.dbusController.set_aptdeamon_environ("init","config")
# 是否查找本地依赖 # 是否查找本地依赖
def _attempt_depends(self,deb_cache, deb_path,_check_local_dep,_auto_satisfy, _install): def _attempt_depends(self,deb_cache, deb_path,_check_local_dep,_auto_satisfy, _install):
depends_list = [] depends_list = []
@ -637,11 +669,9 @@ class UpdateManager():
satisfy_list.append(debfile) satisfy_list.append(debfile)
for depends in noSatisfyList: for depends in noSatisfyList:
for debfile in depends_list: for debfile in depends_list:
if "_" not in debfile and len(debfile.split['_'])!=3:
break
if "%3a" in debfile: if "%3a" in debfile:
debfile=debfile.replace("%3a",":") debfile=debfile.replace("%3a",":")
if depends == debfile.split('_')[0]and debfile not in satisfy_list: if depends.split('_')[0] == debfile.split('_')[0] and depends.split('_')[1] == debfile.split('_')[1] and debfile not in satisfy_list:
depends_count += 1 depends_count += 1
satisfy_list.append(debfile) satisfy_list.append(debfile)
if depends_count < len(noSatisfyList) or depends_count < len(depends_pkg): if depends_count < len(noSatisfyList) or depends_count < len(depends_pkg):
@ -687,7 +717,7 @@ class UpdateManager():
def _suit_install_mode(self, deb_path): def _suit_install_mode(self, deb_path):
self._is_broken = False self._is_broken = False
self.cacheSatisfy = False self.cacheSatisfy = False
_is_install = False _is_install=False
absolute_path, debname = os.path.split(deb_path) absolute_path, debname = os.path.split(deb_path)
# 检查本地破损 # 检查本地破损
try: try:
@ -737,11 +767,11 @@ class UpdateManager():
else: else:
self.cacheSatisfy = False self.cacheSatisfy = False
logging.info("Cache satisfy is %r.",self.cacheSatisfy) logging.info("Cache satisfy is %r.",self.cacheSatisfy)
return deb_cache, install, _is_install return deb_cache,install,_is_install
def _gen_noSatisfyList(self, depends, deb_cache): def _gen_noSatisfyList(self, depends, deb_cache):
_noSatisfyList = [] _noSatisfyList = []
_group_satify = False _group_satify=False
providers = [] providers = []
for or_group in depends: for or_group in depends:
for deb_info in or_group: for deb_info in or_group:
@ -950,7 +980,6 @@ class UpdateInstallMode():
def is_openkylin_desktop(self): def is_openkylin_desktop(self):
return self.dist == self.OPENKYLIN_DISTTRIBUTOR return self.dist == self.OPENKYLIN_DISTTRIBUTOR
# return True
def check_network(self): def check_network(self):
if self.parent.options.no_check_network is False and self.is_disc == False: if self.parent.options.no_check_network is False and self.is_disc == False:
@ -971,14 +1000,12 @@ class UpdateInstallMode():
data = f.read() data = f.read()
important_list = data.split() important_list = data.split()
else: else:
important_list = [self.SYSTEM_UPDATE_GROUPS,self.parent.BACKEND_PKG_NAME,self.parent.APTD_PKG_NAME,self.parent.FRONTEND_PKG_NAME] important_list = [self.SYSTEM_UPDATE_GROUPS]
return important_list
def check_filter(self): #去除重复内容
if self.parent.options.close_filter == False and self.is_disc == False and self.is_openkylin_desktop() == False: important_list = list(set(important_list))
return True
else: return important_list
return False
def _plymouth_splash(self): def _plymouth_splash(self):
if os.path.exists("/bin/plymouth"): if os.path.exists("/bin/plymouth"):
@ -987,6 +1014,17 @@ class UpdateInstallMode():
subprocess.Popen(["/bin/plymouth", "show-splash","--wait"]) subprocess.Popen(["/bin/plymouth", "show-splash","--wait"])
subprocess.call(["/bin/plymouth","system-update","--progress=0"]) subprocess.call(["/bin/plymouth","system-update","--progress=0"])
def _set_inhibit_delay(self,delay_time):
try:
#首先设置systemd默认延长时间为1800
obj = self.bus.get_object('org.freedesktop.login1', '/org/freedesktop/login1')
getter_interface = dbus.Interface(
self.logind_proxy,
dbus_interface='org.freedesktop.login1.Manager')
ret = getter_interface.SetExtraInhibitShutdownDelaySec(delay_time)
except Exception as e:
logging.error(e)
def _inhibit_sleep(self): def _inhibit_sleep(self):
""" """
Send a dbus signal to logind to not suspend the system, it will be Send a dbus signal to logind to not suspend the system, it will be
@ -996,11 +1034,7 @@ class UpdateInstallMode():
from gi.repository import Gio, GLib from gi.repository import Gio, GLib
connection = Gio.bus_get_sync(Gio.BusType.SYSTEM) connection = Gio.bus_get_sync(Gio.BusType.SYSTEM)
#首先设置systemd默认延长时间为1800 self._set_inhibit_delay(1800)
getter_interface = dbus.Interface(
self.logind_proxy,
dbus_interface='org.freedesktop.login1.Manager')
ret = getter_interface.SetInhibitDelayMaxSec(1800)
var, fdlist = connection.call_with_unix_fd_list_sync( var, fdlist = connection.call_with_unix_fd_list_sync(
'org.freedesktop.login1', '/org/freedesktop/login1', 'org.freedesktop.login1', '/org/freedesktop/login1',
@ -1011,11 +1045,10 @@ class UpdateInstallMode():
'delay')), 'delay')),
None, 0, -1, None, None) None, 0, -1, None, None)
inhibitor = Gio.UnixInputStream(fd=fdlist.steal_fds()[var[0]]) inhibitor = Gio.UnixInputStream(fd=fdlist.steal_fds()[var[0]])
return inhibitor return inhibitor
except Exception as e: except Exception as e:
logging.error(e) logging.error(e)
return False return None
def _prompt_in_boot(self): def _prompt_in_boot(self):
#关机安装完成之后开机时进行提醒 #关机安装完成之后开机时进行提醒

View File

@ -75,6 +75,7 @@ class UpdateManagerDbusController(dbus.service.Object):
def _update_important_reply(self,retval): def _update_important_reply(self,retval):
if bool(retval) == False: if bool(retval) == False:
self.InstallDetectStatus(False,enums.get_error_code_from_enum(enums.ERROR_UPDATE_SOURCE_FAILED))
self.UpdateDetectFinished(False,[''],enums.get_error_string_from_enum(enums.ERROR_UPDATE_SOURCE_FAILED),\ self.UpdateDetectFinished(False,[''],enums.get_error_string_from_enum(enums.ERROR_UPDATE_SOURCE_FAILED),\
enums.get_error_description_from_enum(enums.ERROR_UPDATE_SOURCE_FAILED)) enums.get_error_description_from_enum(enums.ERROR_UPDATE_SOURCE_FAILED))
else: else:
@ -82,8 +83,9 @@ class UpdateManagerDbusController(dbus.service.Object):
def _update_important_error(self,retval): def _update_important_error(self,retval):
logging.error(str(retval)) logging.error(str(retval))
self.UpdateDetectFinished(False,[''],enums.get_error_string_from_enum(enums.ERROR_UPDATE_SOURCE_FAILED),\ self.InstallDetectStatus(False,enums.get_error_code_from_enum(enums.ERROR_UPDATE_SOURCE_TIMEOUT))
enums.get_error_description_from_enum(enums.ERROR_UPDATE_SOURCE_FAILED)) self.UpdateDetectFinished(False,[''],enums.get_error_string_from_enum(enums.ERROR_UPDATE_SOURCE_TIMEOUT),\
enums.get_error_description_from_enum(enums.ERROR_UPDATE_SOURCE_TIMEOUT))
#更新important.list的本次升级的列表 #更新important.list的本次升级的列表
def on_update_important_list(self): def on_update_important_list(self):
@ -108,7 +110,7 @@ class UpdateManagerDbusController(dbus.service.Object):
obj = self.bus.get_object('org.debian.apt', '/org/debian/apt') obj = self.bus.get_object('org.debian.apt', '/org/debian/apt')
interface = dbus.Interface(obj, dbus_interface='org.debian.apt') interface = dbus.Interface(obj, dbus_interface='org.debian.apt')
logging.info("Now start to restart Aptdeamon...") logging.info("Now start to restart Aptdeamon...")
interface.Quit() interface.Quit(timeout=0.5)
except Exception as e: except Exception as e:
logging.error(str(e)) logging.error(str(e))
@ -131,14 +133,30 @@ class UpdateManagerDbusController(dbus.service.Object):
try: try:
self.UpdateDetectStatusChanged(5,_("Checking network connection")) self.UpdateDetectStatusChanged(5,_("Checking network connection"))
obj = self.bus.get_object("org.freedesktop.NetworkManager","/org/freedesktop/NetworkManager") obj = self.bus.get_object("org.freedesktop.NetworkManager","/org/freedesktop/NetworkManager")
interface = dbus.Interface(obj, "org.freedesktop.NetworkManager") interface = dbus.Interface(obj, "org.freedesktop.DBus.Properties")
retval = interface.CheckConnectivity(timeout=0.5) retval = interface.Get("org.freedesktop.NetworkManager","Connectivity",timeout=0.5)
except Exception: except Exception:
retval = 4 retval = 4
#1 表示没有网卡可以使用 #1 表示没有网卡可以使用
if retval == 1: if retval == 1:
raise UpdateBaseError(enums.ERROR_NETWORK_FAILED) raise UpdateBaseError(enums.ERROR_NETWORK_FAILED)
def check_connectivity_pro(self):
try:
obj = self.bus.get_object("org.freedesktop.NetworkManager","/org/freedesktop/NetworkManager")
interface = dbus.Interface(obj, "org.freedesktop.NetworkManager")
retval = interface.CheckConnectivity(timeout=15)
except Exception as e:
logging.error("Network status is Exception:" + str(e))
return False
if retval == 4:
logging.info("Network status is Success...")
return True
else:
logging.info("Network status(%d) is Exception...",retval)
return False
def _check_prohibit_user(self, sender_name): def _check_prohibit_user(self, sender_name):
prohibit_list = ["dbus-send","gdbus"] prohibit_list = ["dbus-send","gdbus"]
if sender_name in prohibit_list: if sender_name in prohibit_list:
@ -191,15 +209,15 @@ class UpdateManagerDbusController(dbus.service.Object):
try: try:
if self.parent.configs_cover.has_section(str(section)) and self.parent.configs_cover.has_option(str(section),str(option)): if self.parent.configs_cover.has_section(str(section)) and self.parent.configs_cover.has_option(str(section),str(option)):
value = str(self.parent.configs_cover.get(str(section), str(option))) value = str(self.parent.configs_cover.get(str(section), str(option)))
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+" GetConfigValue section:%s option:%s value:%s ...",section,option,value) # logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+" GetConfigValue section:%s option:%s value:%s ...",section,option,value)
return True,value return True,value
if self.parent.configs_uncover.has_section(str(section)) and self.parent.configs_uncover.has_option(str(section),str(option)): if self.parent.configs_uncover.has_section(str(section)) and self.parent.configs_uncover.has_option(str(section),str(option)):
value = str(self.parent.configs_uncover.get(str(section), str(option))) value = str(self.parent.configs_uncover.get(str(section), str(option)))
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+" GetConfigValue section:%s option:%s value:%s ...",section,option,value) # logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+" GetConfigValue section:%s option:%s value:%s ...",section,option,value)
return True,value return True,value
elif self.parent.sqlite3_server.ucconfigs.has_section(str(section)) and self.parent.sqlite3_server.ucconfigs.has_option(str(section),str(option)): elif self.parent.sqlite3_server.ucconfigs.has_section(str(section)) and self.parent.sqlite3_server.ucconfigs.has_option(str(section),str(option)):
value = str(self.parent.sqlite3_server.ucconfigs.get(str(section), str(option))) value = str(self.parent.sqlite3_server.ucconfigs.get(str(section), str(option)))
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+" GetConfigValue section:%s option:%s value:%s ...",section,option,value) # logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+" GetConfigValue section:%s option:%s value:%s ...",section,option,value)
return True,value return True,value
else: else:
logging.warning("Warning: Can't found section:%s option:%s ... ",section, option) logging.warning("Warning: Can't found section:%s option:%s ... ",section, option)
@ -321,16 +339,11 @@ class UpdateManagerDbusController(dbus.service.Object):
partial_upgrade_list = [str(i) for i in _partial_upgrade_list] partial_upgrade_list = [str(i) for i in _partial_upgrade_list]
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' DistUpgradePartial sender:%s and not_resolver:%r, partial_upgrade_list:%s. ',sender_name,not_resolver,",".join(partial_upgrade_list)) logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' DistUpgradePartial sender:%s and not_resolver:%r, partial_upgrade_list:%s. ',sender_name,not_resolver,",".join(partial_upgrade_list))
self._check_prohibit_user(sender_name) self._check_prohibit_user(sender_name)
local_upgrade_groups = self.parent.update_list.upgrade_meta.upgrade_groups
local_single_pkgs = self.parent.update_list.upgrade_meta.single_pkgs
new_upgrade_list = list(set(partial_upgrade_list) & set(local_upgrade_groups + local_single_pkgs)) if partial_upgrade_list:
if new_upgrade_list:
self.parent.start_install(InstallBackend.MODE_INSTALL_PARTIAL,not_resolver,partial_upgrade_list) self.parent.start_install(InstallBackend.MODE_INSTALL_PARTIAL,not_resolver,partial_upgrade_list)
return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
else: else:
logging.warning('input upgrade list(%s) not in local upgrade_list(%s)',partial_upgrade_list,local_upgrade_groups+local_single_pkgs)
return self.RETURN_BUSY_STATE,self.RETURN_BUSY_DESC return self.RETURN_BUSY_STATE,self.RETURN_BUSY_DESC
except Exception as e: except Exception as e:
logging.info(str(e)) logging.info(str(e))
@ -407,25 +420,28 @@ class UpdateManagerDbusController(dbus.service.Object):
purge_list = [str(pkg) for pkg in _purge_list] purge_list = [str(pkg) for pkg in _purge_list]
sender_name = get_proc_from_dbus_name(sender) sender_name = get_proc_from_dbus_name(sender)
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' DistPurgePackages Sender:%s and purge list is:%s...',sender_name, purge_list) logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' DistPurgePackages Sender:%s and purge list is:%s...',sender_name, purge_list)
(status, details) = PolicyKit_Authority(get_source_name_from_enum(sender_name)+_(" requires authentication to uninstall software packages."), sender) (status, details) = PolicyKit_Authority(get_source_name_from_enum(sender_name)+_(" requires authentication to uninstall software packages."),
sender,source=sender_name)
if not status: if not status:
self.PurgePackagesFinished(False,details,'') self.PurgePackagesFinished(False,details,'')
return self.RETURN_UNKNOWN_CODE,details return self.RETURN_UNKNOWN_CODE,details
#目前只有360使用这个环境变量 当其他包也使用时 可以将这个权限放开 #目前只有360使用这个环境变量 当其他包也使用时 可以将这个权限放开
if "360epp" in purge_list: if True:
#需要对aptdeamon加这两个环境变量 才可以提示弹窗 #需要对aptdeamon加这两个环境变量 才可以提示弹窗
self.set_aptdeamon_environ("XAUTHORITY","/home/"+str(cur_user)+"/.Xauthority") self.set_aptdeamon_environ("XAUTHORITY","/home/"+str(cur_user)+"/.Xauthority")
self.set_aptdeamon_environ("DISPLAY",":0") self.set_aptdeamon_environ("DISPLAY",":0")
# 处于更新和升级中的话 不进行升级 # 处于更新和升级中的话 不进行升级
if self.parent.now_working != InstallBackend.ACTION_DEFUALT_STATUS: if self.parent.now_working != InstallBackend.ACTION_DEFUALT_STATUS:
# self.PurgePackagesFinished(False,_("Other tasks are being updated and upgraded, please uninstall them later."),''," ".join(purge_list))
self.PurgePackagesFinished(False,_("Other tasks are being updated and upgraded, please uninstall them later."),'') self.PurgePackagesFinished(False,_("Other tasks are being updated and upgraded, please uninstall them later."),'')
logging.warning('PurgePackages In the process of updating or Upgrading...') logging.warning('PurgePackages In the process of updating or Upgrading...')
return self.RETURN_BUSY_STATE,self.RETURN_BUSY_DESC return self.RETURN_BUSY_STATE,self.RETURN_BUSY_DESC
else: else:
self._check_prohibit_user(sender_name) self._check_prohibit_user(sender_name)
self.parent.sqlite3_server.current_purge_pkgs = purge_list
self.parent.start_purge_pkgs(purge_list) self.parent.start_purge_pkgs(purge_list)
return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
except Exception as e: except Exception as e:
@ -840,6 +856,16 @@ class UpdateManagerDbusController(dbus.service.Object):
logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" UpdateInstallFinished success = %r , upgrade_group = %a, error_string = %s , error_desc = %s ",\ logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" UpdateInstallFinished success = %r , upgrade_group = %a, error_string = %s , error_desc = %s ",\
success,upgrade_group, error_string,error_desc) success,upgrade_group, error_string,error_desc)
#分步更新安装完成后的弹窗
@dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bs')
def PopupStepsInstalled(self, need_reboot,details_desc=''):
logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" PopupStepsInstalled success = %r ,details_desc = %s ",need_reboot,details_desc)
#分步更新安装中的提示
@dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bs')
def NotifyStepsInstalled(self, reservations,details_desc=''):
logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" NotifyStepsInstalled reservations = %r ,details_desc = %s ",reservations,details_desc)
#升级完成的信号 #升级完成的信号
@dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='basss') @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='basss')
def UpdateDownloadFinished(self, success, upgrade_group,error_string='',error_desc=''): def UpdateDownloadFinished(self, success, upgrade_group,error_string='',error_desc=''):

View File

@ -28,7 +28,7 @@ class UpgradeStrategies():
self.dbusController = self._setup_dbus() self.dbusController = self._setup_dbus()
#config #config
self.uuconfigs = UpgradeConfig(datadir = "/var/lib/unattended-upgrades/", name = "unattended-upgrades-policy.conf") self.uuconfigs = UpgradeConfig(datadir = "/var/lib/unattended-upgrades/", name = "unattended-upgrades-policy.conf")
self.sqlite3_server = Sqlite3Server(self) self.sqlite3_server = Sqlite3Server(self, _no_DataMigration=True)
#策略配置接口的超时退出机制 #策略配置接口的超时退出机制
self.strategy_timestamp = 0 self.strategy_timestamp = 0
GLib.timeout_add_seconds(STRATEGY_IDLE_INTERVAL, GLib.timeout_add_seconds(STRATEGY_IDLE_INTERVAL,

View File

@ -148,9 +148,9 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
logging.info("Apt-p2p service has been disabled and not need to redisabled...") logging.info("Apt-p2p service has been disabled and not need to redisabled...")
return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
else: else:
logging.waring("error: input value _status=%s",status) logging.warning("error: input value _status=%s",status)
else: else:
logging.waring("apt-p2p function is not install...") logging.warning("apt-p2p function is not install...")
## dbus接口: 开启或关闭预下载功能 ## dbus接口: 开启或关闭预下载功能
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='bs', out_signature='b',sender_keyword='sender') @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='bs', out_signature='b',sender_keyword='sender')
@ -360,16 +360,16 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
return False,str(e) return False,str(e)
return True,"success" return True,"success"
# 设置自动更新时间 # # 设置自动更新时间
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='bs',sender_keyword='sender') # @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='bs',sender_keyword='sender')
def SetAutoUpgradePeriod(self, period, sender = None): # def SetAutoUpgradePeriod(self, period, sender = None):
sender_name = get_proc_from_dbus_name(sender) # sender_name = get_proc_from_dbus_name(sender)
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' SetAutoUpgradePeriod will be set value %s, SetAutoUpgradePeriod sender: %s.'%(period, sender_name)) # logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' SetAutoUpgradePeriod will be set value %s, SetAutoUpgradePeriod sender: %s.'%(period, sender_name))
try: # try:
self.parent.sqlite3_server.insert_into_display("update_period", period.lower()) # self.parent.sqlite3_server.insert_into_display("update_period", period.lower())
except Exception as e: # except Exception as e:
logging.error(str(e)) # logging.error(str(e))
return True,"success" # return True,"success"
# 获取数据库值 # 获取数据库值
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='bss', out_signature='s') @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='bss', out_signature='s')

View File

@ -46,10 +46,15 @@ class InstallBackendAptdaemon(InstallBackend):
self.client = client.AptClient() self.client = client.AptClient()
self.trans_failed_msg = None self.trans_failed_msg = None
self.steps_progress_begin = 0
self.steps_progress_end = 0
self.need_retry = False
#是否在安装状态 判断依据进度>50 #是否在安装状态 判断依据进度>50
self.on_install_stage = False self.on_installing = False
if self.action == self.ACTION_INSTALL_SHUTDOWN: if self.action == self.ACTION_INSTALL_SHUTDOWN:
self.on_install_stage = True self.on_installing = True
if self.action == self.ACTION_UPDATE: if self.action == self.ACTION_UPDATE:
#更新的超时检查机制 超时时取消下载 #更新的超时检查机制 超时时取消下载
@ -74,7 +79,7 @@ class InstallBackendAptdaemon(InstallBackend):
if self.aptd_base.progress >= 90 or self.simulation_progress > 80: if self.aptd_base.progress >= 90 or self.simulation_progress > 80:
return False return False
else: else:
self._dist_status_changed(self.action,[],self.simulation_progress,self.aptd_base.status,self.aptd_base.details) self._dist_status_changed(self.action,self.simulation_progress,self.aptd_base.status,self.aptd_base.details)
return True return True
def _check_install_inactivity(self): def _check_install_inactivity(self):
@ -83,6 +88,11 @@ class InstallBackendAptdaemon(InstallBackend):
""" """
logging.info("Checking for inactivity in Installing Time:%d...",self.install_timestamp) logging.info("Checking for inactivity in Installing Time:%d...",self.install_timestamp)
#需要重试下载的话 退出上一个定时器
if self.need_retry == True:
logging.info("Need retry:Installing to exit and timeout check quit...")
return False
if self.window_main.now_working != self.ACTION_INSTALL and self.window_main.now_working != self.ACTION_INSTALL_SHUTDOWN: if self.window_main.now_working != self.ACTION_INSTALL and self.window_main.now_working != self.ACTION_INSTALL_SHUTDOWN:
logging.info("Installing to exit and timeout check quit...") logging.info("Installing to exit and timeout check quit...")
return False return False
@ -93,7 +103,7 @@ class InstallBackendAptdaemon(InstallBackend):
self.install_timestamp = INSTALL_IDLE_TIMEOUT self.install_timestamp = INSTALL_IDLE_TIMEOUT
#只有安装的时候启用 下载时候不使用 #只有安装的时候启用 下载时候不使用
if (self.install_timestamp <= 0 and self.on_install_stage == True): if (self.install_timestamp <= 0 and self.on_installing == True):
logging.error("Quitting due to inactivity(%s)",self.aptd_base.details) logging.error("Quitting due to inactivity(%s)",self.aptd_base.details)
if self.action == self.ACTION_INSTALL_SHUTDOWN: if self.action == self.ACTION_INSTALL_SHUTDOWN:
#关机安装模式 解除禁止关机锁 #关机安装模式 解除禁止关机锁
@ -108,7 +118,7 @@ class InstallBackendAptdaemon(InstallBackend):
error_string=_("Could not install the upgrades"), error_string=_("Could not install the upgrades"),
error_desc=_("Installtion timeout to exit Due to inactivity") + self.aptd_base.details) error_desc=_("Installtion timeout to exit Due to inactivity") + self.aptd_base.details)
# self.window_main.dbusController.Quit(None) # self.dbus_send.Quit(None)
return False return False
else: else:
self.install_timestamp = self.install_timestamp - 1 self.install_timestamp = self.install_timestamp - 1
@ -133,7 +143,7 @@ class InstallBackendAptdaemon(InstallBackend):
and self.aptd_base.cancelable == True: and self.aptd_base.cancelable == True:
logging.error("Quitting due to inactivity") logging.error("Quitting due to inactivity")
self.window_main.dbusController.transaction.cancel() self.dbus_send.transaction.cancel()
return False return False
return True return True
@ -143,7 +153,7 @@ class InstallBackendAptdaemon(InstallBackend):
"""刷新包cache""" """刷新包cache"""
try: try:
trans = yield self.client.update_cache(defer=True) trans = yield self.client.update_cache(defer=True)
self.window_main.dbusController.transaction = trans self.dbus_send.transaction = trans
# 注册回调函数 接收更新的状态 # 注册回调函数 接收更新的状态
yield self._show_transaction(trans, self.ACTION_UPDATE, yield self._show_transaction(trans, self.ACTION_UPDATE,
_("Checking for updates…"), False) _("Checking for updates…"), False)
@ -165,7 +175,7 @@ class InstallBackendAptdaemon(InstallBackend):
trans = yield self.client.commit_packages( trans = yield self.client.commit_packages(
pkgs_install, reinstall, pkgs_remove, purge = purge, upgrade = pkgs_upgrade, pkgs_install, reinstall, pkgs_remove, purge = purge, upgrade = pkgs_upgrade,
downgrade = pkgs_downgrade,defer=True) downgrade = pkgs_downgrade,defer=True)
self.window_main.dbusController.transaction = trans self.dbus_send.transaction = trans
yield self._show_transaction(trans, self.action, yield self._show_transaction(trans, self.action,
_("Installing updates…"), True) _("Installing updates…"), True)
@ -195,7 +205,7 @@ class InstallBackendAptdaemon(InstallBackend):
trans = yield self.client.commit_only( trans = yield self.client.commit_only(
pkgs_install, reinstall, pkgs_remove, purge = purge, upgrade = pkgs_upgrade, pkgs_install, reinstall, pkgs_remove, purge = purge, upgrade = pkgs_upgrade,
downgrade = pkgs_downgrade,download = model, defer=True) downgrade = pkgs_downgrade,download = model, defer=True)
self.window_main.dbusController.transaction = trans self.dbus_send.transaction = trans
yield self._show_transaction(trans, self.action, yield self._show_transaction(trans, self.action,
_("Installing updates…"), True) _("Installing updates…"), True)
@ -217,6 +227,43 @@ class InstallBackendAptdaemon(InstallBackend):
error_string='', error_desc='') error_string='', error_desc='')
raise raise
@inline_callbacks
def commit_steps(self,model,pkgs_install, pkgs_upgrade, pkgs_remove,begin=0,end=100,last_steps=False):
"""Commit a list of package adds and removes"""
try:
reinstall = purge = downgrade = []
trans = yield self.client.commit_only(
pkgs_install, reinstall, pkgs_remove, purge = purge, upgrade = pkgs_upgrade,
downgrade = downgrade,download = model, defer=True)
self.dbus_send.transaction = trans
self.steps_progress_begin = begin
self.steps_progress_end = end
if last_steps == True:
yield self._show_transaction(trans, self.action,
_("Installing updates…"), True)
else:
yield self._show_transaction_steps(trans, self.action,
_("Installing updates…"), True)
except errors.NotAuthorizedError:
self._action_done(self.action,
authorized=False, success=False,
error_string='', error_desc='')
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":
raise
self._action_done(self.action,
authorized=False, success=False,
error_string='', error_desc='')
except Exception:
self._action_done(self.action,
is_cancelled=False, success=False,
error_string='', error_desc='')
raise
@inline_callbacks @inline_callbacks
def install_deb(self,install_path,install_force): def install_deb(self,install_path,install_force):
"""安装deb包 """ """安装deb包 """
@ -232,7 +279,7 @@ class InstallBackendAptdaemon(InstallBackend):
except Exception as e: except Exception as e:
self._action_done(self.ACTION_INSTALL_DEB, self._action_done(self.ACTION_INSTALL_DEB,
is_cancelled=False, success=False, is_cancelled=False, success=False,
error_string=str(e), error_desc='') error_string=str(e), error_desc='', error_code=e.code)
# raise # raise
@inline_callbacks @inline_callbacks
@ -240,7 +287,7 @@ class InstallBackendAptdaemon(InstallBackend):
"""安装deb包 """ """安装deb包 """
try: try:
trans = yield self.client.fix_broken_depends(defer=True) trans = yield self.client.fix_broken_depends(defer=True)
self.window_main.dbusController.transaction = trans self.dbus_send.transaction = trans
# 注册回调函数 接收更新的状态 # 注册回调函数 接收更新的状态
yield self._show_transaction(trans, self.ACTION_FIX_BROKEN, yield self._show_transaction(trans, self.ACTION_FIX_BROKEN,
_("Installing deb packages…"), False) _("Installing deb packages…"), False)
@ -259,7 +306,7 @@ class InstallBackendAptdaemon(InstallBackend):
"""修复未完成的安装 """ """修复未完成的安装 """
try: try:
trans = yield self.client.fix_incomplete_install(defer=True) trans = yield self.client.fix_incomplete_install(defer=True)
self.window_main.dbusController.transaction = trans self.dbus_send.transaction = trans
# 注册回调函数 接收更新的状态 # 注册回调函数 接收更新的状态
yield self._show_transaction(trans, self.ACTION_FIX_INCOMPLETE, yield self._show_transaction(trans, self.ACTION_FIX_INCOMPLETE,
_("fix incomplete install"), False) _("fix incomplete install"), False)
@ -278,7 +325,7 @@ class InstallBackendAptdaemon(InstallBackend):
"""清空所有下载的文件 """ """清空所有下载的文件 """
try: try:
trans = yield self.client.clean(defer=True) trans = yield self.client.clean(defer=True)
self.window_main.dbusController.transaction = trans self.dbus_send.transaction = trans
# 注册回调函数 接收更新的状态 # 注册回调函数 接收更新的状态
yield self._show_transaction(trans, self.ACTION_CLEAN, yield self._show_transaction(trans, self.ACTION_CLEAN,
_("Remove all downloaded files."), False) _("Remove all downloaded files."), False)
@ -298,7 +345,7 @@ class InstallBackendAptdaemon(InstallBackend):
try: try:
# trans = yield self.client.remove_packages(package_names = pkgs_purge,defer=True) # trans = yield self.client.remove_packages(package_names = pkgs_purge,defer=True)
trans = yield self.client.commit_packages([],[],[],pkgs_purge,[],[],defer=True) trans = yield self.client.commit_packages([],[],[],pkgs_purge,[],[],defer=True)
self.window_main.dbusController.transaction = trans self.dbus_send.transaction = trans
# 注册回调函数 接收更新的状态 # 注册回调函数 接收更新的状态
yield self._show_transaction(trans, self.ACTION_REMOVE_PACKAGES, yield self._show_transaction(trans, self.ACTION_REMOVE_PACKAGES,
_("Installing deb packages…"), False) _("Installing deb packages…"), False)
@ -308,9 +355,6 @@ class InstallBackendAptdaemon(InstallBackend):
error_string='', error_desc='') error_string='', error_desc='')
except Exception as e: except Exception as e:
logging.error(str(e)) logging.error(str(e))
# 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): def _on_progress_changed(self, trans,progress,action):
@ -318,15 +362,18 @@ class InstallBackendAptdaemon(InstallBackend):
if progress == 101: if progress == 101:
return return
#过滤掉不是线性的进度 if self.action_mode == self.MODE_INSTALL_STEP:
if progress > self.aptd_base.progress: progress = int(self.steps_progress_begin + (progress / 100) *
self.aptd_base.progress = progress (self.steps_progress_end - self.steps_progress_begin))
else: else:
return #过滤掉不是线性的进度
if progress > self.aptd_base.progress:
self.aptd_base.progress = progress
else:
return
self.aptd_base.progress = progress self.aptd_base.progress = progress
self._dist_status_changed(action,self.now_upgrade.upgrade_content,self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details) self._dist_status_changed(action,self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details)
#同步状态回调 #同步状态回调
def _on_status_changed(self, trans, status,action): def _on_status_changed(self, trans, status,action):
@ -338,66 +385,63 @@ class InstallBackendAptdaemon(InstallBackend):
if self.aptd_base.status == None: if self.aptd_base.status == None:
return return
self._dist_status_changed(action,self.now_upgrade.upgrade_content,\ self._dist_status_changed(action,self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details)
self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details)
#分发进度状态和细节信息 #分发进度状态和细节信息
def _dist_status_changed(self,action,upgrade_content = [],progress = 0,status = '',details = ''): def _dist_status_changed(self,action,progress = 0,status = '',details = ''):
if action == self.ACTION_UPDATE: # 更新进度100后推迟发出100%的信号 -- 等待源过滤完成 if action == self.ACTION_UPDATE: # 更新进度100后推迟发出100%的信号 -- 等待源过滤完成
if progress == 11: if progress == 11:
progress = 15 progress = 15
if progress != 100: if progress != 100:
self.window_main.dbusController.UpdateDetectStatusChanged(progress,status) self.dbus_send.UpdateDetectStatusChanged(progress,status)
elif action == self.ACTION_INSTALL: elif action == self.ACTION_INSTALL:
#50%时候 属于下载状态切换到安装状态的过程 下面的代码只执行一次 if self.meta_upgrade.version_upgrade == True and progress >= 48 and 'Failed to fetch' in self.aptd_base.error_details:
if progress >= 50 and progress < 90 and self.on_install_stage == False:
logging.info("The process is now in the installtion phase")
self.on_install_stage = True
self.safe_manager.shutdown_safe()
self._start_install_lock(_("Kylin System Updater"))
#只处理从下载切换到安装时出现的网络问题
#当网络波动时下载某些软件包失败时属于异常状态进行重试时 不发送后续进度 等待重试正常是 进行下载安装
if self.now_upgrade.version_upgrade == True and progress >= 48 and self.on_install_stage != True and 'Failed to fetch' in self.aptd_base.error_details:
logging.warning("Arise Failed to fetch and Need retry Upgrade...") logging.warning("Arise Failed to fetch and Need retry Upgrade...")
self.now_upgrade.need_retry = True self.need_retry = True
return return
#在下载阶段发送取消信号 #50%时候 属于下载状态切换到安装状态的过程 下面的代码只执行一次
if self.on_install_stage == False: #在安装的阶段的时候就进入安装阶段 禁止关机操作
self.window_main.dbusController.Cancelable(self.aptd_base.cancelable) #提前进度安装状态
if progress >= 49 and progress < 90 and self.on_installing == False:
self.on_installing = True
self.entering_installed()
self.window_main.dbusController.UpdateDloadAndInstStaChanged(upgrade_content,progress,status,details) #在下载阶段发送取消信号
elif action == self.ACTION_INSTALL_SHUTDOWN: if self.on_installing == False:
# 写入进度 到plymouth self.dbus_send.Cancelable(self.aptd_base.cancelable)
self._progress_to_plymouth(progress)
self.window_main.dbusController.UpdateDloadAndInstStaChanged(upgrade_content,progress,status,details) self.dbus_send.UpdateDloadAndInstStaChanged(self.meta_upgrade.get_content(),progress,status,details)
elif action == self.ACTION_DOWNLOADONLY: elif action == self.ACTION_DOWNLOADONLY:
#只处理从下载切换到安装时出现的网络问题 #只处理从下载切换到安装时出现的网络问题
#当网络波动时下载某些软件包失败时属于异常状态进行重试时 不发送后续进度 等待重试正常是 进行下载安装 #当网络波动时下载某些软件包失败时属于异常状态进行重试时 不发送后续进度 等待重试正常是 进行下载安装
if self.now_upgrade.version_upgrade == True and progress >= 48 and 'Failed to fetch' in self.aptd_base.error_details: if self.meta_upgrade.version_upgrade == True and 'Failed to fetch' in self.aptd_base.error_details:
logging.warning("Arise Failed to fetch and Need retry Upgrade...") logging.warning("Arise Failed to fetch and Need retry Upgrade...")
self.now_upgrade.need_retry = True self.need_retry = True
return return
self.window_main.dbusController.Cancelable(self.aptd_base.cancelable) self.dbus_send.Cancelable(self.aptd_base.cancelable)
self.window_main.dbusController.UpdateDloadAndInstStaChanged(upgrade_content,progress,status,details) self.dbus_send.UpdateDloadAndInstStaChanged(self.meta_upgrade.get_content(),progress,status,details)
elif action == self.ACTION_INSTALL_SHUTDOWN:
# 写入进度 到plymouth
self._progress_to_plymouth(progress)
self.dbus_send.UpdateDloadAndInstStaChanged(self.meta_upgrade.get_content(),progress,status,details)
elif action == self.ACTION_FIX_BROKEN: elif action == self.ACTION_FIX_BROKEN:
self.window_main.dbusController.FixBrokenStatusChanged(False,True,progress,status,'','') self.dbus_send.FixBrokenStatusChanged(False,True,progress,status,'','')
elif action == self.ACTION_REMOVE_PACKAGES: elif action == self.ACTION_REMOVE_PACKAGES:
self.window_main.dbusController.PurgePkgStatusChanged(progress,status,details) self.dbus_send.PurgePkgStatusChanged(progress,status,details)
elif action == self.ACTION_INSTALL_DEB or action == self.ACTION_BACKGROUND_UPGRADE: elif action == self.ACTION_INSTALL_DEB or action == self.ACTION_BACKGROUND_UPGRADE:
self.window_main.dbusController.InstalldebStatusChanged(progress,status,details) self.dbus_send.InstalldebStatusChanged(progress,status,details)
else: else:
logging.info("Other Action:progress = %d , status = %s ,details = %s",progress,status,details) logging.info("Other Action:progress = %d , status = %s ,details = %s",progress,status,details)
def _on_details_changed(self, trans, details,action): def _on_details_changed(self, trans, details,action):
self.aptd_base.details = details self.aptd_base.details = details
self._dist_status_changed(action,self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs,\ self._dist_status_changed(action,self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details)
self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details)
def _on_download_changed(self, trans, details): def _on_download_changed(self, trans, details):
logging.info(details) logging.info(details)
@ -405,8 +449,7 @@ class InstallBackendAptdaemon(InstallBackend):
# eta 剩余时间不正确,取消掉 # eta 剩余时间不正确,取消掉
def _on_progress_download_changed(self,trans,current_items, total_items, currenty_bytes, total_bytes, current_cps, eta): def _on_progress_download_changed(self,trans,current_items, total_items, currenty_bytes, total_bytes, current_cps, eta):
if self.action == self.ACTION_INSTALL or self.action == self.ACTION_DOWNLOADONLY or self.action == self.ACTION_BACKGROUND_UPGRADE: if self.action == self.ACTION_INSTALL or self.action == self.ACTION_DOWNLOADONLY or self.action == self.ACTION_BACKGROUND_UPGRADE:
self.window_main.dbusController.UpdateDownloadInfo(\ self.dbus_send.UpdateDownloadInfo(self.meta_upgrade.get_content(),\
self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs,\
current_items, total_items, \ current_items, total_items, \
currenty_bytes, total_bytes, \ currenty_bytes, total_bytes, \
current_cps) current_cps)
@ -425,27 +468,25 @@ class InstallBackendAptdaemon(InstallBackend):
if self.action != self.ACTION_UPDATE: if self.action != self.ACTION_UPDATE:
logging.info("\033[1;32m" + "Emitting" + "\033[0m" +" Cancelable: %r",Cancelable) logging.info("\033[1;32m" + "Emitting" + "\033[0m" +" Cancelable: %r",Cancelable)
self.window_main.dbusController.Cancelable(Cancelable) self.dbus_send.Cancelable(Cancelable)
#增加取消信号的频发机制 #增加取消信号的频发机制
self.aptd_base.cancelable = Cancelable self.aptd_base.cancelable = Cancelable
def _on_config_file_conflict(self, transaction, old, new): def _on_config_file_conflict(self, transaction, old, new):
logging.info("Config file conflict oldconf = %s , newconf = %s...",str(old),str(new)) logging.info("Config file conflict oldconf = %s , newconf = %s...",str(old),str(new))
logging.info("Default To Replace Old Configfile...") logging.info("Default To Replace Old Configfile...")
#默认替换旧的配置文件
transaction.resolve_config_file_conflict(old, "keep") transaction.resolve_config_file_conflict(old, "keep")
# transaction.resolve_config_file_conflict(old, "keep")
#增加记录当产生错误的时候 详细信息 #增加记录当产生错误的时候 详细信息
def _on_error_changed(self, trans,error_code, error_details): def _on_error_changed(self, trans,error_code, error_details):
# error_string = get_error_string_from_enum(error_code)
self.aptd_base.error_details = str(error_details) self.aptd_base.error_details = str(error_details)
logging.error(str(error_details)) logging.error(str(error_details))
@inline_callbacks @inline_callbacks
def _show_transaction(self, trans, action, header, show_details): def _show_transaction_steps(self, trans, action, header, show_details):
#更新和升级最后完成和失败都会走此在此进行完成之后的处理
trans.connect("finished", self._on_finished, action) trans.connect("finished", self._on_finished_steps, action)
#升级和更新的状态信息和进度 #升级和更新的状态信息和进度
trans.connect("status-changed", self._on_status_changed,action) trans.connect("status-changed", self._on_status_changed,action)
trans.connect("progress-changed", self._on_progress_changed,action) trans.connect("progress-changed", self._on_progress_changed,action)
@ -458,18 +499,47 @@ class InstallBackendAptdaemon(InstallBackend):
trans.connect("config-file-conflict", self._on_config_file_conflict) trans.connect("config-file-conflict", self._on_config_file_conflict)
# yield trans.set_debconf_frontend("ukui")
# yield trans.set_locale(os.environ["LANGUAGE"] + ".UTF-8")
yield trans.run() yield trans.run()
@inline_callbacks
def _show_transaction(self, trans, action, header, show_details):
if action == self.ACTION_INSTALL_DEB:
trans.connect("finished", self._on_finished_special, action)
else:
trans.connect("finished", self._on_finished, action)
#升级和更新的状态信息和进度
trans.connect("status-changed", self._on_status_changed,action)
trans.connect("progress-changed", self._on_progress_changed,action)
#取消升级
trans.connect("cancellable-changed", self._on_cancellable_changed)
#下载的进度信息
trans.connect("progress-details-changed", self._on_progress_download_changed)
trans.connect("status-details-changed", self._on_details_changed,action)
trans.connect("error", self._on_error_changed)
trans.connect("config-file-conflict", self._on_config_file_conflict)
yield trans.run()
def _on_finished_steps(self, trans, status, action):
try:
if status == EXIT_SUCCESS:
self._steps_done()
else:
self._on_finished(trans, status, action)
except Exception as e:
logging.error(e)
traceback.print_exc()
def _on_finished(self, trans, status, action): def _on_finished(self, trans, status, action):
try: try:
error_string = '' error_string = ''
error_desc = '' error_desc = ''
#退出 error_code = ''
self.on_install_stage = False
if status == EXIT_FAILED: if status == EXIT_FAILED:
# self.log_audit(str(trans.error.code)) # self.log_audit(str(trans.error.code))
error_code = trans.error.code
error_string = get_error_string_from_enum(trans.error.code) error_string = get_error_string_from_enum(trans.error.code)
error_desc = get_error_description_from_enum(trans.error.code) error_desc = get_error_description_from_enum(trans.error.code)
if self.trans_failed_msg: if self.trans_failed_msg:
@ -479,14 +549,36 @@ class InstallBackendAptdaemon(InstallBackend):
error_string = _("Failed to fetch") error_string = _("Failed to fetch")
error_desc = _("_Cancel Upgrade") error_desc = _("_Cancel Upgrade")
elif status == EXIT_SUCCESS and action == self.ACTION_INSTALL: elif status == EXIT_SUCCESS and action == self.ACTION_INSTALL:
error_string = _("System upgrade is complete.") pass
elif status == EXIT_SUCCESS and action == self.ACTION_REMOVE_PACKAGES: elif status == EXIT_SUCCESS and action == self.ACTION_REMOVE_PACKAGES:
error_string = _("Uninstallation completed") error_string = _("Uninstallation completed")
is_success = (status == EXIT_SUCCESS) is_success = (status == EXIT_SUCCESS)
self._action_done(action, self._action_done(action,
is_cancelled=(status == EXIT_CANCELLED), success=is_success, is_cancelled=(status == EXIT_CANCELLED), success=is_success,
error_string=error_string, error_desc=error_desc) error_string=error_string, error_desc=error_desc,error_code=error_code)
except Exception as e:
logging.error(e)
traceback.print_exc()
def _on_finished_special(self, trans, status, action):
try:
error_string = ''
error_desc = ''
error_code = ''
if status == EXIT_FAILED and action == self.ACTION_INSTALL_DEB:
error_code = trans.error.code
error_string = get_error_string_from_enum(trans.error.code)
error_desc = get_error_description_from_enum(trans.error.code)
if str(error_code) == 'error-dep-resolution-failed':
status,detailed_information,err_info = self.window_main.start_deb_resolver(self.window_main.sqlite3_server.deb_metadata['deblist'])
is_success = ((status == EXIT_SUCCESS) or (status == 0))
self._action_done(action,
is_cancelled=(status == EXIT_CANCELLED), success=is_success,
error_string=error_string, error_desc=error_desc,error_code=error_code)
except Exception as e: except Exception as e:
logging.error(e) logging.error(e)
traceback.print_exc() traceback.print_exc()

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,10 @@
<vendor_url>www.kylinos.cn</vendor_url> <vendor_url>www.kylinos.cn</vendor_url>
<icon_name>kylin-system-updater</icon_name> <icon_name>kylin-system-updater</icon_name>
<action id="cn.kylinos.KylinSystemUpdater.action"> <!--Kylin Installer Config-->
<action id="cn.kylin.installer.action">
<_description> <_description>
system level settings Configuration items added for Kirin Installer
</_description> </_description>
<_message> <_message>
To Change the settings, you need to authenticate. To Change the settings, you need to authenticate.
@ -22,4 +23,47 @@
</defaults> </defaults>
</action> </action>
<action id="cn.kylin.uninstaller.action">
<_description>
Configuration items added for Kirin Uninstaller
</_description>
<_message>
To Change the settings, you need to authenticate.
</_message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<!--Kylin System Updater Config-->
<action id="cn.kylinos.KylinSystemUpdater.action">
<_description>
Configuration items added for Kirin Installer
</_description>
<_message>
To Change the settings, you need to authenticate.
</_message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<!--Kylin Software Center Config-->
<action id="cn.kylin.software.center.action">
<_description>
Configuration items added for Kylin Software Center
</_description>
<_message>
To Change the settings, you need to authenticate.
</_message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
</action>
</policyconfig> </policyconfig>

View File

@ -1,4 +1,4 @@
[D-BUS Service] [D-BUS Service]
Name=com.kylin.UpgradeStrategies Name=com.kylin.UpgradeStrategies
Exec=/bin/python3 /usr/share/kylin-system-updater/kylin-upgrade-strategies -r -d Exec=/usr/share/kylin-system-updater/kylin-upgrade-strategies
User=root User=root

Binary file not shown.

View File

@ -1,5 +1,6 @@
[SystemStatus] [SystemStatus]
abnormal_reboot = False abnormal_reboot = False
reboot_update = False
upload_upgrade_log = True upload_upgrade_log = True
upload_installer_log = False upload_installer_log = False

View File

@ -6,7 +6,7 @@ autoUpgradeState = off
preDownload = off preDownload = off
# 预下载的时间为时间段 例如10:00-11:00 # 预下载的时间为时间段 例如10:00-11:00
preDownloadTime = 10:00 preDownloadTime = 00:00-06:00
#添加检查更新的周期 以天为单位 #添加检查更新的周期 以天为单位
updateDays = 1 updateDays = 1
@ -15,13 +15,16 @@ updateDays = 1
downloadMode = timing downloadMode = timing
# 下载的时间为时间段 例如10:00-11:00 # 下载的时间为时间段 例如10:00-11:00
downloadTime = 10:00 downloadTime = 00:00-05:00
#安装存在定时timing 手动:manual 关机安装bshutdown #安装存在定时timing 手动:manual 关机安装bshutdown
installMode = timing installMode = timing
#安装也为时间段 例如00:00 #安装也为时间段 例如00:00
installTime = 10:00 installTime = 05:30-06:00
#立即更新随机波动范围(单位:分钟)
randomRange = 60
#是否开启自动重启 以及自动重启时间可以调节 #是否开启自动重启 以及自动重启时间可以调节
automaticReboot = off automaticReboot = off

View File

@ -1 +1,5 @@
0 [timestamp]
predownload = 2022-01-01 00:00:00
download = 2022-01-01 00:00:00
install = 2022-01-01 00:00:00
download_and_install = 2022-01-01 00:00:00

View File

@ -83,7 +83,7 @@ if __name__ == "__main__":
signal.signal(signal.SIGINT,signal_handler_term) signal.signal(signal.SIGINT,signal_handler_term)
if options.debug: if options.debug:
logging.basicConfig(format=FORMAT,level=logging.INFO,datefmt='%m-%d,%H:%M:%S') logging.basicConfig(format=FORMAT,level=logging.DEBUG,datefmt='%m-%d,%H:%M:%S')
else: else:
logging.basicConfig(format=FORMAT,level=logging.DEBUG,datefmt='%m-%d,%H:%M:%S',filename = logfile(),filemode = 'a') logging.basicConfig(format=FORMAT,level=logging.DEBUG,datefmt='%m-%d,%H:%M:%S',filename = logfile(),filemode = 'a')
@ -91,13 +91,14 @@ if __name__ == "__main__":
app = UpdateManager(options) app = UpdateManager(options)
#当出现安装过程中异常的重启时 开机直接进行修复操作
# if app.configs_cover.getWithDefault("ConfigPkgStatus", "check_frontend_pkg", False) == True:
# app.configs_cover.setValue("ConfigPkgStatus","check_frontend_pkg",str(False),True)
# app.check_frontend_pkg()
#当出现安装过程中异常的重启时 开机直接进行修复操作 #当出现安装过程中异常的重启时 开机直接进行修复操作
if app.configs_uncover.getWithDefault("SystemStatus", "abnormal_reboot", False) == True: if app.configs_uncover.getWithDefault("SystemStatus", "abnormal_reboot", False) == True:
app.configs_uncover.setValue("SystemStatus","abnormal_reboot",str(False),True)
app.start_update() app.start_update()
#自我升级完成后 初始化列表
if app.configs_uncover.getWithDefault("SystemStatus", "reboot_update", False) == True:
app.configs_uncover.setValue("SystemStatus","reboot_update",str(False),True)
app.start_available()
app.run() app.run()

226
backend/po/bo_CN.po Normal file
View File

@ -0,0 +1,226 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: kylinos.cn\n"
"POT-Creation-Date: 2012-06-14 00:53+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "Unable to access the source management server, please try again later"
msgstr "འདྲི་རྩད་ཀྱི་འབྱུང་ཁུངས་དོ་དམ་ཞབས་ཞུའི་ཡོ་བྱད་ལ་འཚམས་འདྲི་བྱེད་ཐབས་མེད་པས་རྗེས་སུ་ཡང་བསྐྱར"
msgid "Access to the source management server timed out, please try again later"
msgstr "འཚམས་འདྲིའི་འབྱུང་ཁུངས་ཀྱི་དོ་དམ་ཞབས་ཞུའི་ཡོ་བྱད་དུས་ལས་བརྒལ་བས་རྗེས་སུ་ཡང་བསྐྱར་ཚོད་ལྟ་བྱེད་རོགས"
msgid "Check if your network requires authentication?"
msgstr "ཁྱེད་ཀྱི་དྲ་རྒྱར་ཞིབ་བཤེར་བྱེད་དགོས་སམ།"
msgid "Check your source public key signature"
msgstr "ཁྱེད་ཀྱི་འབྱུང་ཁུངས་ལ་ཞིབ་བཤེར་བྱས་ནས་མིང་རྟགས་བཀོད།"
msgid "update important list occur Exception"
msgstr "ལག་ཏུ་བླངས་ནས་རྒྱུན་ལྡན་མིན་པ་བྱུང་ན་རྗེས་སུ་ཡང་བསྐྱར་ཚོད་ལྟ་ཞིག་གནང་རོགས།"
msgid "You need to be root to run this application"
msgstr "ཁྱོད་ལ་rootཡི་དབང་ཚད་ལྟར་འཁོར་སྐྱོད་བྱེད་དགོས།"
msgid "There is an exception in the update package."
msgstr "ཁུག་མ་གསར་སྒྱུར་བྱས་པ་རྒྱུན་ལྡན་མིན་པ་ཞིག་རེད"
msgid "You request the removal of a system-essential package."
msgstr "ཁྱེད་ཀྱིས་མ་ལག་ཅིག་གི་དགོས་ངེས་ཀྱི་མཉེན་ཆས་ཁུག་མ་ཞིག་བསུབ་དགོས་པའི་བླང་བྱ་"
msgid "This update cannot detect the upgradeable package."
msgstr "ཐེངས་འདིའི་གསར་སྒྱུར་གྱིས་རིམ་འཕར་ཐུབ་པའི་མཉེན་ཆས་ཁུག་མར་ཞིབ་དཔྱད་ཚད་ལེན་བྱེད་ཐབས་མེད།"
msgid "read important list failed"
msgstr "རིམ་པ་སྤོར་བའི་རེའུ་མིག་ཀློག་ཐབས་བྲལ་བས་རྗེས་སུ་ཡང་བསྐྱར་ཚོད་ལྟ་ཞིག་བྱེད་རོགས།"
msgid "Priority Upgrade Package being updated"
msgstr "ཁག་བགོས་ཀྱི་བཀོད་སྒྲིག་གསར་སྒྱུར་བྱེད་བཞིན་ཡོད།"
msgid "Exceptions of Priority Upgrade."
msgstr "དམིགས་སུ་བཀར་ནས་དམིགས་སུ་བཀར་ནས་རིམ་པ"
msgid "Due to the presence of deleted packages."
msgstr "བསུབ་པའི་མཉེན་ཆས་ཁུག་མ་ཡོད་པའི་རྐྱེན་གྱིས།"
msgid "The system update configuration file is read abnormally, please check if the system update configuration file format is correct."
msgstr "མ་ལག་གསར་སྒྱུར་བཀོད་སྒྲིག་ཡིག་ཆ་རྒྱུན་ལྡན་མིན་པས། ཞིབ་བཤེར་མ་ལག་གི་བཀོད་སྒྲིག་ཡིག་ཆའི་རྣམ་གཞག་ཡང་དག་ཡིན་མིན་ལ་ཞིབ་བཤེར་གནང་རོགས།"
msgid "Installation progress: "
msgstr "སྒྲིག་སྦྱོར་མྱུར་ཚད་གཤམ་གསལ། "
msgid "Installation successful, about to shut down"
msgstr "སྒྲིག་སྦྱོར་ལེགས་འགྲུབ་བྱུང་བ་དང་འགག་སྒོ་ལས་སྒྲོལ་གྲབས་ཡོད་"
msgid "Installation failed, about to shut down"
msgstr "སྒྲིག་སྦྱོར་བྱས་ནས་ཕམ་ཉེས་བྱུང་ན་སྒོ་རྒྱག་ལ་ཉེ།"
msgid "groups JSON ConfigPkgs install failed"
msgstr "ཁག་བགོས་ཀྱིས་ཡིག་ཆ་སྒྲིག་སྦྱོར་བྱེད་ཐབས་མེད།"
msgid "Installtion timeout to exit Due to inactivity"
msgstr "སྒྲིག་སྦྱོར་བྱེད་སྐབས་ཕྱིར་འཐེན་བྱས་པའི་རྐྱེན་གྱིས་རེད།"
msgid "Command execution error"
msgstr "ཚགས་པར་འདོན་ནོར་ཤོར་བའི་བཀའ་ཕབ་པ།"
msgid "Unsupported architecture"
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 "ཁབ་ལེན་གྱི་བར་སྟོང་མི་འདང་བས་ཁབ་ལེན་སྡེར་མ་གཙང་བཤེར་བྱས་རྗེས་རིམ་སྤར་གསར་སྒྱུར་བྱེད་རོགས།"
msgid "Network anomaly, can't check for updates!"
msgstr "དྲ་རྒྱ་རྒྱུན་ལྡན་མིན་པས་ཞིབ་བཤེར་གསར་སྒྱུར་བྱེད་ཐབས་མེད།"
msgid "Check for update exceptions!"
msgstr "རྒྱུན་ལྡན་མིན་པར་ཞིབ་བཤེར་བྱེད་པ།"
msgid "Check for update exceptions,fix system APT environment error."
msgstr "ཞིབ་བཤེར་གསར་སྒྱུར་མ་ལག་APTཡི་ཁོར་ཡུག་ལ་ནོར་འཁྲུལ་བྱུང་བ་རེད།"
msgid "The system APT environment is abnormal, please check the system APT environment."
msgstr "མ་ལག་APTཡི་ཁོར་ཡུག་རྒྱུན་ལྡན་མིན་པར་ཉམས་གསོ་བྱེད་པར་མ་ལག་APTཡི་ཁོར་ཡུག་ལ་ཞིབ་བཤེར་གནང་རོགས།"
msgid "Priority upgrade status exception."
msgstr "དམིགས་སུ་བཀར་ནས་རིམ་པ་འཕར་བའི་རྣམ་པ་རྒྱུན་ལྡན་མིན་པ"
msgid "Upgrade configuration acquisition exception."
msgstr "རིམ་སྤར་བཀོད་སྒྲིག་ལ་རྒྱུན་ལྡན་མིན་པའི་གྲུབ་འབྲས་ཐོབ་པ་རེད།"
msgid "Please check your network connection and retry."
msgstr "ཁྱེད་ཀྱི་དྲ་རྒྱ་འབྲེལ་མཐུད་བྱས་རྗེས་ཡང་བསྐྱར་ཚོད་ལྟ་ཞིག་བྱེད་རོགས།"
msgid "Please check your source list and retry."
msgstr "ཁྱེད་ཀྱི་འབྱུང་ཁུངས་རེའུ་མིག་ལ་ཞིབ་བཤེར་བྱས་རྗེས་ཡང་བསྐྱར་ཚོད་ལྟ་བྱོས།"
msgid "Checking network connection"
msgstr "དྲ་རྒྱ་སྦྲེལ་མཐུད་བྱེད་པར་ཞིབ་བཤེར་བྱ་དགོས།"
msgid "Updating Source Template"
msgstr "འབྱུང་ཁུངས་གསར་སྒྱུར་བྱེད་པའི་མ་དཔེའི་ནང་།"
msgid "Update Manager upgrade is complete, please restart the setting panel before performing the system update."
msgstr "དོ་དམ་ཡོ་བྱད་རིམ་སྤར་ལེགས་འགྲུབ་བྱུང་བ་དང་། གསར་བཅོས་བྱས་རྗེས་སླར་ཡང་མ་ལག་གསར་སྒྱུར་བྱེད་རོགས།"
msgid "Uninstallation completed"
msgstr "ཕབ་ལེན་ལེགས་འགྲུབ་བྱུང་བ།"
msgid "Package validation failed and installation was rejected."
msgstr "མཉེན་ཆས་ཚོད་ལྟས་ར་སྤྲོད་བྱས་ནས་ཕམ་ཁ་བྱུང་བས་སྒྲིག་སྦྱོར་དང་ལེན་མ་བྱས"
msgid "Other tasks are being updated and upgraded, please uninstall them later."
msgstr "ལས་འགན་གཞན་དག་གསར་སྒྱུར་རིམ་སྤོར་བྱེད་བཞིན་པའི་སྒང་ཡིན་"
#: ../aptdaemon/worker/aptworker.py:1353
msgid "The following packages have unmet dependencies:"
msgstr "གཤམ་གསལ་གྱི་མཉེན་ཆས་ཁུག་མ་ཡིད་ཚིམ་པའི་གཞན་རྟེན་གྱི་འབྲེལ་བ།"
#: ../aptdaemon/worker/aptworker.py:1406
msgid "but it is a virtual package"
msgstr "འོན་ཀྱང་དེ་ནི་རྟོག་བཟོའི་མཉེན་ཆས་ཁུག་མ་རེད།"
#: ../aptdaemon/worker/aptworker.py:1409
msgid "but it is not installed"
msgstr "但是 %s 没有安装"
#: ../aptdaemon/worker/aptworker.py:1411
msgid "but it is not going to be installed"
msgstr "但是无法安装 %s"
#. TRANSLATORS: %s is a version number
#: ../aptdaemon/worker/aptworker.py:1415
#, python-format
msgid "but %s is installed"
msgstr "但是 %s 已经安装"
#. TRANSLATORS: %s is a version number
#: ../aptdaemon/worker/aptworker.py:1419
#, python-format
msgid "but %s is to be installed"
msgstr "但是将要安装 %s"
#: ../SystemUpdater/Core/enums.py:763
msgid "Kylin System Updater"
msgstr "ཝེ།སྒྲིག་ཆས་གསར་སྒྱུར་བྱེད་དགོས།"
#: ../SystemUpdater/Core/enums.py:609
msgid "Kylin Installer"
msgstr "ཝེ།སྒྲིག་ཆས་སྒྲིག་སྦྱོར་བྱེད་དགོས།"
#: ../SystemUpdater/Core/enums.py:610
msgid "Kylin Uninstaller"
msgstr "ཝེ།བཏགས་ཆས་"
#: ../SystemUpdater/Core/enums.py:611
msgid "Kylin Background Upgrade"
msgstr "ཁ་རོག་གེར་གསར་སྒྱུར་བྱེད་པ།"
#: ../SystemUpdater/Core/enums.py:612
msgid "Kylin Software Center"
msgstr "མཉེན་ཆས་ཚོང་ཁང་།"
#: ../SystemUpdater/UpdateManagerDbus.py:355
msgid " requires authentication to uninstall software packages."
msgstr "མཉེན་ཆས་ཀྱི་ཁུག་མ་འདོན་པར་བདེན་དཔང་ར་སྤྲོད་བྱེད་དགོས།"
#. 验签失败,提权
#: ../SystemUpdater/UpdateManager.py:463
msgid " requires authentication to install software packages."
msgstr "མཉེན་ཆས་ཀྱི་ཁུག་མ་སྒྲིག་སྦྱོར་བྱེད་པར་བདེན་དཔང་ར་སྤྲོད་བྱེད"
#: ../SystemUpdater/Core/utils.py:750
msgid "Authentication success."
msgstr "བདེན་དཔང་ར་སྤྲོད་ལེགས་འགྲུབ་བྱུང་"
#: ../SystemUpdater/Core/utils.py:753
msgid "Authentication failure."
msgstr "བདེན་དཔང་ར་སྤྲོད་ཕམ་སོང་།"
#: ../SystemUpdater/Core/enums.py:101
msgid "Deb format exception, read local deb file error."
msgstr "མཉེན་ཆས་ཀྱི་ཁུག་མའི་རྣམ་གཞག་རྒྱུན་ལྡན་མིན་པས་ཕམ་ཁ་བླངས།"
#: ../SystemUpdater/Core/enums.py:102
msgid "Install deb error."
msgstr "མཉེན་ཆས་སྒྲིག་སྦྱོར་བྱས་པ་ཕམ་སོང་།"
msgid "Upgrade System"
msgstr "ཁྱོན་ཡོངས་ནས་རིམ་སྤར་བྱ་དགོས།"
msgid "kylin-unattended-upgrade"
msgstr "རང་འགུལ་གྱིས་གསར་སྒྱུར་བྱེད་དགོས།"
msgid "Please check the system time and synchronize the system time before updating."
msgstr "མ་ལག་གི་དུས་ཚོད་ལ་ཞིབ་བཤེར་གནང་རོགས། དུས་མཉམ་དུ་མ་ལག་གི་དུས་ཚོད་རྗེས་སུ་གསར་སྒྱུར་བྱེད་དགོས"
msgid "The package is unsigned, refuses to install."
msgstr "མཉེན་ཆས་ཀྱི་ཁུག་མར་མིང་རྟགས་མ་བཀོད་པས་སྒྲིག་སྦྱོར་དང་ལེན་མི་བྱེད།"
msgid "Program exception, please contact the administrator to solve."
msgstr "གོ་རིམ་ལག་བསྟར་རྒྱུན་ལྡན་མིན་པར་དོ་དམ་པ་དང་འབྲེལ་གཏུག་བྱས་ནས་ཐག་གཅོད"
msgid "Exceptions to running the check script."
msgstr "འཁོར་སྐྱོད་ཞིབ་བཤེར་གྱི་རྐང་པར་རྒྱུན་ལྡན་མིན་པ་བྱུང་།"

View File

@ -2563,9 +2563,12 @@ msgstr ""
msgid "%.0f kB" msgid "%.0f kB"
msgstr "%.0f kB" msgstr "%.0f kB"
msgid "Unable to access the source management server" msgid "Unable to access the source management server, please try again later"
msgstr "无法访问源管理服务器,请稍后再试" msgstr "无法访问源管理服务器,请稍后再试"
msgid "Access to the source management server timed out, please try again later"
msgstr "访问源管理服务器超时,请稍后再试"
msgid "Check if your network requires authentication?" msgid "Check if your network requires authentication?"
msgstr "检查您的网络需要认证吗?" msgstr "检查您的网络需要认证吗?"
@ -2761,3 +2764,12 @@ msgstr "请检查系统时间,同步系统时间后再进行更新。"
msgid "The package is unsigned, refuses to install." msgid "The package is unsigned, refuses to install."
msgstr "软件包未签名,拒绝安装。" msgstr "软件包未签名,拒绝安装。"
msgid "Program exception, please contact the administrator to solve."
msgstr "程序执行异常,请联系管理员解决。"
msgid "Exceptions to running the check script."
msgstr "运行检查脚本出现异常。"
msgid "Installing or removing software packages."
msgstr "正在安装或删除软件包。"

View File

@ -2525,7 +2525,7 @@ msgstr "因 grub 已安裝,移除 lilo (詳情見 bug #314004"
#~ msgstr "提取檔案及安裝升級可能要花數小時。一旦下載完成即不能取消升級程序。" #~ msgstr "提取檔案及安裝升級可能要花數小時。一旦下載完成即不能取消升級程序。"
msgid "Unable to access the source management server" msgid "Unable to access the source management server, please try again later"
msgstr "無法存取來源管理伺服器,請稍後再試" msgstr "無法存取來源管理伺服器,請稍後再試"
msgid "Check if your network requires authentication?" msgid "Check if your network requires authentication?"

View File

@ -2557,7 +2557,7 @@ msgstr "因已安裝 grub移除 lilo。詳情見 bug #314004。"
#~ "請稍後從「管理」選單選擇「更新管理員」。" #~ "請稍後從「管理」選單選擇「更新管理員」。"
msgid "Unable to access the source management server" msgid "Unable to access the source management server, please try again later"
msgstr "無法存取來源管理伺服器,請稍後再試" msgstr "無法存取來源管理伺服器,請稍後再試"
msgid "Check if your network requires authentication?" msgid "Check if your network requires authentication?"

View File

@ -26,6 +26,8 @@ cp -r /var/log/apt/history.log updaterlog || true
#收集aptdamon的日志 #收集aptdamon的日志
cp -r /var/log/kylin-unattended-upgrades/ updaterlog || true cp -r /var/log/kylin-unattended-upgrades/ updaterlog || true
#收集前端日志
cp -r /var/run/user/1000/kylin-update-frontend.log updaterlog || true
outputName="$(date +%m-%d,%H-%M-%S)-updaterLog.tar.gz" outputName="$(date +%m-%d,%H-%M-%S)-updaterLog.tar.gz"

9
debian/changelog vendored
View File

@ -1,3 +1,12 @@
kylin-system-updater (2.0.5.15-ok4) yangtze; urgency=medium
* BUG: #无
* 需求号: 无
* 其他改动说明: 同步2303主线代码
* 其他改动影响域:系统更新
-- Kevin Duan <duankaiwen@kylinos.cn> Mon, 29 May 2023 14:47:14 +0800
kylin-system-updater (2.0.5.15-ok3) yangtze; urgency=medium kylin-system-updater (2.0.5.15-ok3) yangtze; urgency=medium
* BUG: #无 * BUG: #无

View File

@ -45,7 +45,7 @@ import grp
import io import io
import locale import locale
import logging import logging
import logging.handlers
import re import re
import os import os
import select import select
@ -108,14 +108,16 @@ HTTPTYPE = "HTTP"
FTPTYPE = "FTP" FTPTYPE = "FTP"
ARCHITECTUREMAP = ['arm64','amd64','armhf','i386','loongarch64','mips64el','sw64'] ARCHITECTUREMAP = ['arm64','amd64','armhf','i386','loongarch64','mips64el','sw64']
KYLIN_VERSION_FILE = "/etc/kylin-version/kylin-system-version.conf" VERSION_FILE = '/etc/kylin-version/kylin-system-version.conf'
OTA_RESULT_FILE_PATH="/opt/apt_result/" OTA_RESULT_FILE_PATH="/opt/apt_result/"
OTA_RESULT_FILE="/opt/apt_result/ota_result" OTA_RESULT_FILE="/opt/apt_result/ota_result"
SYSTEM_UPDATER_CORE_LIB_PATH="/usr/share/kylin-system-updater/SystemUpdater/Core" #SYSTEM_UPDATER_CORE_LIB_PATH="/usr/share/kylin-system-updater/SystemUpdater/Core"
# sys.path.append(SYSTEM_UPDATER_CORE_LIB_PATH) # sys.path.append(SYSTEM_UPDATER_CORE_LIB_PATH)
# from OriginFilter import UnattendUpgradeFilter # from OriginFilter import UnattendUpgradeFilter
KYLIN_VERSION_FILE = "/etc/kylin-version/kylin-system-version.conf"
CONFIG_FILE_ROOT_PATH="/var/lib/unattended-upgrades" CONFIG_FILE_ROOT_PATH="/var/lib/unattended-upgrades"
UNATTENDED_UPGRADE_CONFIG_FILE_PATH="/var/lib/unattended-upgrades/unattended-upgrade.conf" UNATTENDED_UPGRADE_CONFIG_FILE_PATH="/var/lib/unattended-upgrades/unattended-upgrade.conf"
UNATTENDED_UPGRADE_POLICY_FILE_PATH="/var/lib/unattended-upgrades/unattended-upgrades-policy.conf"
WHITE_LIST_FILE_PATH="/var/lib/kylin-system-updater/system-updater.conf" WHITE_LIST_FILE_PATH="/var/lib/kylin-system-updater/system-updater.conf"
TIMESTAMP_PATH="/var/lib/kylin-software-properties/template/kylin-source-status" TIMESTAMP_PATH="/var/lib/kylin-software-properties/template/kylin-source-status"
CONTROL_PANEL_LOCK_FILE = "/tmp/auto-upgrade/ukui-control-center.lock" CONTROL_PANEL_LOCK_FILE = "/tmp/auto-upgrade/ukui-control-center.lock"
@ -152,76 +154,15 @@ pidfile = None
# set from the sigint signal handler # set from the sigint signal handler
SIGNAL_STOP_REQUEST = False SIGNAL_STOP_REQUEST = False
class PackageComponent(): def kysec_pre_upgrade():
def MarkUpgrade(self): if os.path.exists("/usr/share/kysec-maintain/sys-upgrade-pre.sh"):
pass logging.debug("kysec pre-upgrade settings...")
subprocess.run(["/bin/sh","/usr/share/kysec-maintain/sys-upgrade-pre.sh"])
def MarkInstall(self): def kysec_post_upgrade():
pass if os.path.exists("/usr/share/kysec-maintain/sys-upgrade-post.sh"):
logging.debug("kysec post-upgrade settings...")
subprocess.run(["/bin/sh","/usr/share/kysec-maintain/sys-upgrade-post.sh"])
class PackageGroup(PackageComponent):
def __init__(self,name) -> None:
self.name = name
self.upgrade_list = []
self.install_list = []
def AddCache(self,cache):
for pkg in self.upgrade_list:
pkg.AddCache(cache)
for pkg in self.install_list:
pkg.AddCache(cache)
def FindPackage(self,name):
for pkg in self.upgrade_list:
if pkg.FindPackage(name):
return True
for pkg in self.install_list:
if pkg.FindPackage(name):
return True
return False
def AddPackageToUpgradeList(self,Package):
self.upgrade_list.append(Package)
def RemovePackageFromUpgradeList(self,Package):
if Package in self.upgrade_list:
self.upgrade_list.remove(Package)
def AddPackageToInstallList(self,Package):
self.install_list.append(Package)
def RemovePackageFromInstallList(self,Package):
if Package in self.install_list:
self.install_list.remove(Package)
def MarkUpgrade(self):
for package in self.upgrade_list:
package.MarkUpgrade()
def MarkInstall(self):
for package in self.install_list:
package.MarkInstall()
class Package(PackageComponent):
def __init__(self,name,version) -> None:
self.name = name
self.candidate_version = version
self.deps = []
def FindPackage(self,name):
if name in self.deps:
return True
return False
def AddCache(self,cache):
self.cache = cache
def MarkUpgrade(self):
return
def MarkInstall(self):
return
def reload_options_config(): def reload_options_config():
#添加默认保留旧配置 #添加默认保留旧配置
@ -243,7 +184,6 @@ def reload_options_config():
apt_pkg.config["Dir::Etc::sourceparts"]="" apt_pkg.config["Dir::Etc::sourceparts"]=""
apt_pkg.init_system() apt_pkg.init_system()
def get_default_version(): def get_default_version():
version = "" version = ""
data = {'version':""} data = {'version':""}
@ -259,7 +199,7 @@ def get_default_version():
return version return version
def ReadOsRelease(file): def ReadOsRelease(file):
osreleasedict={} osreleasedict = {}
try: try:
with open(file) as f: with open(file) as f:
lines = f.readlines() lines = f.readlines()
@ -268,11 +208,13 @@ def ReadOsRelease(file):
osreleasedict.update({ls[0]:ls[1].strip('"')}) osreleasedict.update({ls[0]:ls[1].strip('"')})
except Exception as e: except Exception as e:
pass pass
if 'PROJECT_CODENAME' not in osreleasedict.keys():
osreleasedict.update({'PROJECT_CODENAME':''})
if 'SUB_PROJECT_CODENAME' not in osreleasedict.keys(): if 'SUB_PROJECT_CODENAME' not in osreleasedict.keys():
osreleasedict.update({'SUB_PROJECT_CODENAME':''}) osreleasedict.update({'SUB_PROJECT_CODENAME':''})
return osreleasedict return osreleasedict
'''
#安装时禁止关机 进行加锁 #安装时禁止关机 进行加锁
def LockedPreventShutdown(): def LockedPreventShutdown():
global pidfile global pidfile
@ -331,6 +273,7 @@ def unLockedEnableShutdown():
pidfile.close() pidfile.close()
pidfile = None pidfile = None
return False return False
'''
def is_dpkg_journal_dirty(): def is_dpkg_journal_dirty():
# type: () -> bool # type: () -> bool
@ -363,6 +306,7 @@ def get_white_list_with_version(srclist,list,namelist):
def get_timestamp(): def get_timestamp():
global timeStamp global timeStamp
config=configparser.ConfigParser(allow_no_value=True) config=configparser.ConfigParser(allow_no_value=True)
config.optionxform = str
config.read(TIMESTAMP_PATH) config.read(TIMESTAMP_PATH)
time_value=time.localtime(int(config.get("Server","UpdateTime"))) time_value=time.localtime(int(config.get("Server","UpdateTime")))
logging.debug(("获取软件源时间戳:%s"),time_value) logging.debug(("获取软件源时间戳:%s"),time_value)
@ -372,6 +316,7 @@ def get_timestamp():
def WriteValueToFile(file,section,option,value): def WriteValueToFile(file,section,option,value):
config=configparser.ConfigParser(allow_no_value=True) config=configparser.ConfigParser(allow_no_value=True)
config.optionxform = str
config.add_section(section) config.add_section(section)
config.set(section,option,value) config.set(section,option,value)
config.write(open(file,"w")) config.write(open(file,"w"))
@ -400,6 +345,7 @@ logged_msgs = set() # type: AbstractSet[str]
NEVER_PIN = -32768 NEVER_PIN = -32768
class InhibitShutdownLock(): class InhibitShutdownLock():
def __init__(self): def __init__(self):
@ -718,34 +664,6 @@ class OriginProperty():
except Exception as e: except Exception as e:
logging.error(str(e)) logging.error(str(e))
def get_allowed_origins(allow_origin):
""" return a list of allowed origins
"""
allowed_origins = []
origin = ''
archive = ''
uri = ''
label = ''
for ao in (allow_origin['http']+allow_origin['ftp']):
if 'origin' in ao['release']:
origin = 'o='+ao['release']['origin']
else:
origin = 'o='
if 'archive' in ao['release']:
archive = 'a='+ao['release']['archive']
else:
archive = 'a='
if 'label' in ao['release']:
label = 'l='+ao['release']['label']
else:
label = 'l='
if 'origin_source' in ao:
uri = 'uri='+ao['origin_source']
else:
uri = 'uri='
allowed_origins.append(origin+","+archive+","+label+","+uri)
return allowed_origins
def deleteDuplicatedElementFromList(list): def deleteDuplicatedElementFromList(list):
resultList = [] resultList = []
for item in list: for item in list:
@ -850,7 +768,6 @@ class KylinSystemUpdater:
def ConnectToSignals(self): def ConnectToSignals(self):
def update_detect_finished_handler(success,updatelist,error_status,error_cause): def update_detect_finished_handler(success,updatelist,error_status,error_cause):
logging.debug(updatelist)
if success: if success:
logging.info("update detect success,quiting main loop") logging.info("update detect success,quiting main loop")
self.update_group = updatelist self.update_group = updatelist
@ -872,11 +789,6 @@ class KylinSystemUpdater:
PackageGroup.AddPackageToInstallList(Package(key,data['install_list'][key]['new_version'])) PackageGroup.AddPackageToInstallList(Package(key,data['install_list'][key]['new_version']))
# install_list.append((key,data['install_list'][key]['new_version'])) # install_list.append((key,data['install_list'][key]['new_version']))
self.group_list.append(gp) self.group_list.append(gp)
for key in data['upgrade_list'].keys():
self.whitelist_with_candidate_version.append((key,data['upgrade_list'][key]['new_version']))
for key in data['install_list'].keys():
self.whitelist_with_candidate_version.append((key,data['install_list'][key]['new_version']))
''' '''
for key in data['upgrade_list'].keys(): for key in data['upgrade_list'].keys():
if key in ["total_download_size","total_install_size"]: if key in ["total_download_size","total_install_size"]:
@ -1020,6 +932,7 @@ class KylinBackupManager:
def ReadValueFromFile(file,section,option): def ReadValueFromFile(file,section,option):
config=configparser.ConfigParser(allow_no_value=True) config=configparser.ConfigParser(allow_no_value=True)
config.optionxform = str
try: try:
config.read(file) config.read(file)
value = config[section][option] value = config[section][option]
@ -1031,15 +944,19 @@ def Backup():
# do backup # do backup
kylin_backup_manager = KylinBackupManager() kylin_backup_manager = KylinBackupManager()
backup_partition_status = kylin_backup_manager.mount_backup_partition() backup_partition_status = kylin_backup_manager.mount_backup_partition()
logging.info("backup partition status:%d"%backup_partition_status)
if backup_partition_status not in [0,5]: if backup_partition_status not in [0,5]:
logging.error("backup partition error:%d"%backup_partition_status) logging.error("backup partition error:%d"%backup_partition_status)
return UnattendedUpgradesResult(False,"backup partition error") # return UnattendedUpgradesResult(False,"backup partition error")
return False
status_code,result = kylin_backup_manager.get_backup_state() status_code,result = kylin_backup_manager.get_backup_state()
if result == 0 and status_code == 99: if result == 0 and status_code == 99:
pass pass
else: else:
logging.error("backup state error:",status_code,result) logging.error("backup state error:",status_code,result)
return UnattendedUpgradesResult(False,"backup state error") # return UnattendedUpgradesResult(False,"backup state error")
return False
#node_name,node_status = kylin_backup_manager.get_backup_comment_for_systemupdate() #node_name,node_status = kylin_backup_manager.get_backup_comment_for_systemupdate()
ts = get_timestamp() ts = get_timestamp()
kylin_backup_manager.ConnectToSignals() kylin_backup_manager.ConnectToSignals()
@ -1050,6 +967,7 @@ def Backup():
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","backup") WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","backup")
kylin_backup_manager.auto_backup_for_system_update_noreturn(ts,create_note,inc_note,userName,uid) kylin_backup_manager.auto_backup_for_system_update_noreturn(ts,create_note,inc_note,userName,uid)
kylin_backup_manager.RunMainloop() kylin_backup_manager.RunMainloop()
return True
''' '''
if node_name != timeStamp: if node_name != timeStamp:
logging.info("need backup") logging.info("need backup")
@ -1072,11 +990,9 @@ class UnattendedUpgradesCache(apt.Cache):
def __init__(self, rootdir, whitelist_with_version,blacklist): def __init__(self, rootdir, whitelist_with_version,blacklist):
self._cached_candidate_pkgnames = set() # type: Set[str] # self._cached_candidate_pkgnames = set() # type: Set[str]
unattended_upgrade_filter = UnattendUpgradeFilter()
self.origin_filter = UnattendUpgradeFilter() self.allowed_origins = unattended_upgrade_filter.GetAllowOrigins()
self.allowed_origins = self.origin_filter.GetAllowOrigins()
logging.info(_("Allowed origins are: %s"), logging.info(_("Allowed origins are: %s"),
", ".join(self.allowed_origins)) ", ".join(self.allowed_origins))
@ -1275,7 +1191,7 @@ class UnattendedUpgradesCache(apt.Cache):
def adjust_candidate_with_version(self,pkg,version): def adjust_candidate_with_version(self,pkg,version):
for v in pkg.versions: for v in pkg.versions:
if v.version == version and is_in_allowed_origin(v,self.allowed_origins): if v.version == version and is_in_allowed_origin(v,self.allowed_origins):
#logging.debug("pkg %s adjusting candidate version: %s" %(pkg.name,v)) logging.debug("pkg %s adjusting candidate version: %s" %(pkg.name,v))
pkg.candidate = v pkg.candidate = v
return True return True
return False return False
@ -1791,28 +1707,35 @@ def get_allowed_origins_legacy():
raise raise
return allowed_origins return allowed_origins
'''
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. def get_allowed_origins(allow_origin):
""" return a list of allowed origins
""" """
allowed_origins = []
allowed_origins = get_allowed_origins_legacy() origin = ''
key = "Unattended-Upgrade::Origins-Pattern" archive = ''
try: uri = ''
for s in apt_pkg.config.value_list(key): label = ''
allowed_origins.append(substitute(s)) for ao in (allow_origin['http']+allow_origin['ftp']):
except ValueError: if 'origin' in ao['release']:
logging.error(_("Unable to parse %s." % key)) origin = 'o='+ao['release']['origin']
raise else:
origin = 'o='
#logging.info("allowed origins are:%s"%"\n".join(allowed_origins)) if 'archive' in ao['release']:
archive = 'a='+ao['release']['archive']
else:
archive = 'a='
if 'label' in ao['release']:
label = 'l='+ao['release']['label']
else:
label = 'l='
if 'origin_source' in ao:
uri = 'uri='+ao['origin_source']
else:
uri = 'uri='
allowed_origins.append(origin+","+archive+","+label+","+uri)
return allowed_origins return allowed_origins
'''
def match_whitelist_string(whitelist, origin): def match_whitelist_string(whitelist, origin):
# type: (str, Union[apt.package.Origin, apt_pkg.PackageFile]) -> bool # type: (str, Union[apt.package.Origin, apt_pkg.PackageFile]) -> bool
@ -2134,12 +2057,21 @@ def sanity_problem(cache, desired_pkg):
# return ("no package is selected to be upgraded or installed") # return ("no package is selected to be upgraded or installed")
changes = cache.get_changes() changes = cache.get_changes()
if desired_pkg and desired_pkg not in changes:
logging.warning("pkg %s to be marked for upgrade/install is not marked accordingly" % desired_pkg.name)
return False
pkgs_to_remove = []
for pkg in changes: for pkg in changes:
if pkg.marked_delete:
logging.warning("pkg %s is marked to be deleted" % pkg.name)
pkgs_to_remove.append(pkg.name)
'''
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis': if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
pass pass
elif pkg.marked_delete: elif pkg.marked_delete:
return ("pkg %s is marked to be deleted" % pkg.name) logging.warning("pkg %s is marked to be deleted" % pkg.name)
pkgs_to_remove.append(pkg.name)
if pkg.marked_install or pkg.marked_upgrade: if pkg.marked_install or pkg.marked_upgrade:
# apt will never fallback from a trusted to a untrusted # apt will never fallback from a trusted to a untrusted
@ -2149,16 +2081,16 @@ def sanity_problem(cache, desired_pkg):
# return ("pkg %s is not from a trusted origin" % pkg.name) # return ("pkg %s is not from a trusted origin" % pkg.name)
if not is_in_allowed_origin(pkg.candidate, cache.allowed_origins): if not is_in_allowed_origin(pkg.candidate, cache.allowed_origins):
return ("pkg %s is not in an allowed origin" % pkg.name) return ("pkg %s is not in an allowed origin" % pkg.name)
'''
if not is_pkg_change_allowed(pkg, if not is_pkg_change_allowed(pkg,
cache.blacklist, cache.blacklist,
cache.whitelist, cache.whitelist,
cache.strict_whitelist): cache.strict_whitelist):
return ("pkg %s is blacklisted or is not whitelisted" return ("pkg %s is blacklisted or is not whitelisted"
% pkg.name) % pkg.name)
'''
# check if the package is unsafe to upgrade unattended # check if the package is unsafe to upgrade unattended
'''
ignore_require_restart = apt_pkg.config.find_b( ignore_require_restart = apt_pkg.config.find_b(
"Unattended-Upgrade::IgnoreAppsRequireRestart", False) "Unattended-Upgrade::IgnoreAppsRequireRestart", False)
upgrade_requires = pkg.candidate.record.get("Upgrade-Requires") upgrade_requires = pkg.candidate.record.get("Upgrade-Requires")
@ -2167,12 +2099,17 @@ def sanity_problem(cache, desired_pkg):
and upgrade_requires == "app-restart": and upgrade_requires == "app-restart":
return ("pkg %s requires app-restart, it is not safe to " return ("pkg %s requires app-restart, it is not safe to "
"upgrade it unattended") "upgrade it unattended")
'''
# check that the package we want to upgrade is in the change set # check that the package we want to upgrade is in the change set
if desired_pkg and desired_pkg not in changes: if desired_pkg and desired_pkg not in changes:
return ("pkg %s to be marked for upgrade/install is not marked " logging.warning("pkg %s to be marked for upgrade/install is not marked "
"accordingly" % desired_pkg.name) "accordingly" % desired_pkg.name)
return None return False
'''
if len(pkgs_to_remove) > 0:
logging.debug("pkgs marked to delete:%s"%",".join(pkgs_to_remove))
return False
return True
def is_deb(file): def is_deb(file):
@ -2653,37 +2590,38 @@ def _setup_logging(options,logfile):
# apt_pkg.config.set("Debug::pkgDepCache::AutoInstall", "1") # apt_pkg.config.set("Debug::pkgDepCache::AutoInstall", "1")
if options.debug: if options.debug:
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
stdout_handler = logging.StreamHandler(sys.stdout) # stdout_handler = logging.StreamHandler(sys.stdout)
logger.addHandler(stdout_handler) # logger.addHandler(stdout_handler)
elif options.verbose: elif options.verbose:
logger.setLevel(logging.INFO) logger.setLevel(logging.INFO)
stdout_handler = logging.StreamHandler(sys.stdout) stdout_handler = logging.StreamHandler(sys.stdout)
logger.addHandler(stdout_handler) logger.addHandler(stdout_handler)
# if apt_pkg.config.find("Unattended-Upgrade::Mail", ""): '''
# mem_log_handler = logging.StreamHandler(mem_log) if apt_pkg.config.find("Unattended-Upgrade::Mail", ""):
# logger.addHandler(mem_log_handler) mem_log_handler = logging.StreamHandler(mem_log)
# Configure syslog if necessary logger.addHandler(mem_log_handler)
# syslogEnable = apt_pkg.config.find_b("Unattended-Upgrade::SyslogEnable", Configure syslog if necessary
# False) syslogEnable = apt_pkg.config.find_b("Unattended-Upgrade::SyslogEnable",
# if syslogEnable: False)
# syslogFacility = apt_pkg.config.find( if syslogEnable:
# "Unattended-Upgrade::SyslogFacility", syslogFacility = apt_pkg.config.find(
# "daemon") "Unattended-Upgrade::SyslogFacility",
# syslogHandler = logging.handlers.SysLogHandler( "daemon")
# address='/dev/log', syslogHandler = logging.handlers.SysLogHandler(
# facility=syslogFacility) # type: ignore address='/dev/log',
# syslogHandler.setFormatter( facility=syslogFacility) # type: ignore
# logging.Formatter("unattended-upgrade: %(message)s")) syslogHandler.setFormatter(
# known = syslogHandler.facility_names.keys() # type: ignore logging.Formatter("unattended-upgrade: %(message)s"))
# if syslogFacility.lower() in known: known = syslogHandler.facility_names.keys() # type: ignore
# logger.addHandler(syslogHandler) if syslogFacility.lower() in known:
# logging.info("Enabled logging to syslog via %s facility " logger.addHandler(syslogHandler)
# % syslogFacility) logging.info("Enabled logging to syslog via %s facility "
# else: % syslogFacility)
# logging.warning("Syslog facility %s was not found" else:
# % syslogFacility) logging.warning("Syslog facility %s was not found"
# return mem_log % syslogFacility)
return mem_log
'''
def logged_in_users(): def logged_in_users():
# type: () -> AbstractSet[str] # type: () -> AbstractSet[str]
@ -2694,6 +2632,24 @@ def logged_in_users():
USERS, universal_newlines=True).rstrip('\n') USERS, universal_newlines=True).rstrip('\n')
return set(users.split()) return set(users.split())
def reboot_if_needed():
# type: () -> None
"""auto-reboot (if required and the config for this is set)"""
if not os.path.exists(REBOOT_REQUIRED_FILE):
return
needreboot = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH,"autoUpgradePolicy","automaticReboot")
if needreboot == 'off':
return
# reboot at the specified time
when = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH,"autoUpgradePolicy","automaticRebootTime")
logging.warning("Found %s, rebooting" % REBOOT_REQUIRED_FILE)
cmd = ["/sbin/shutdown", "-r", when]
try:
shutdown_msg = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
if shutdown_msg.strip():
logging.warning("Shutdown msg: %s", shutdown_msg.strip())
except Exception as e:
logging.error("Failed to issue shutdown: %s", e)
def reboot_if_requested_and_needed(): def reboot_if_requested_and_needed():
# type: () -> None # type: () -> None
@ -2757,7 +2713,7 @@ def try_to_upgrade(pkg, # type: apt.Package
except NoAllowedOriginError: except NoAllowedOriginError:
return return
cache._cached_candidate_pkgnames.add(pkg.name) # cache._cached_candidate_pkgnames.add(pkg.name)
if not pkg.installed: if not pkg.installed:
cache.mark_install_adjusted(pkg,from_user=True) cache.mark_install_adjusted(pkg,from_user=True)
else: else:
@ -2794,9 +2750,27 @@ def calculate_upgradable_pkgs(cache, # type: UnattendedUpgradesCache
for pkgname in whitelist: for pkgname in whitelist:
try: try:
pkg = cache[pkgname[0]] pkg = cache[pkgname[0]]
adjust_candidate_result = cache.adjust_candidate_with_version(pkg,pkgname[1])
if (not adjust_candidate_result):
logging.warning("%s-%s :can not adjust candidate version"%(pkgname[0],pkgname[1]))
continue
if not pkg.installed:
cache.mark_install_adjusted(pkg,from_user=True)
elif pkg.is_upgradable:
cache.mark_upgrade_adjusted(pkg, from_user=not pkg.is_auto_installed)
else:
pass
if sanity_problem(cache,pkg):
pkgs_to_upgrade.append(pkg)
except Exception as e: except Exception as e:
logging.error("error checking pkg:%s"%e) logging.error("error checking pkg:%s"%e)
continue continue
'''
if check_changes_for_sanity(cache, pkg):
# add to packages to upgrade
pkgs_to_upgrade.append(pkg)
'''
#for pkg in cache: #for pkg in cache:
# if pkg.name not in cache.whitelist: # if pkg.name not in cache.whitelist:
# logging.debug("%s not in whitelist skipping..."%(pkg.name)) # logging.debug("%s not in whitelist skipping..."%(pkg.name))
@ -2806,7 +2780,7 @@ def calculate_upgradable_pkgs(cache, # type: UnattendedUpgradesCache
or candidate_version_changed(pkg): or candidate_version_changed(pkg):
logging.debug("Checking: %s (%s)" % ( logging.debug("Checking: %s (%s)" % (
pkg.name, getattr(pkg.candidate, "origins", []))) pkg.name, getattr(pkg.candidate, "origins", [])))
'''
if (pkg.is_upgradable or candidate_version_changed(pkg) or not pkg.is_installed): if (pkg.is_upgradable or candidate_version_changed(pkg) or not pkg.is_installed):
try: try:
ver_in_allowed_origin(pkg, cache.allowed_origins) ver_in_allowed_origin(pkg, cache.allowed_origins)
@ -2814,15 +2788,15 @@ def calculate_upgradable_pkgs(cache, # type: UnattendedUpgradesCache
continue continue
try_to_upgrade(pkg, try_to_upgrade(pkg,
pkgs_to_upgrade, pkgs_to_upgrade,
cache,pkgname[1]) cache,pkgname[1])
'''
# logging.debug("Checking: %s (%s)" % ( # logging.debug("Checking: %s (%s)" % (
# pkg.name, getattr(pkg.candidate, "origins", []))) # pkg.name, getattr(pkg.candidate, "origins", [])))
#pkgs_to_upgrade.append(pkg) #pkgs_to_upgrade.append(pkg)
if cache.get_changes(): if cache.get_changes():
cache.clear() cache.clear()
return pkgs_to_upgrade return pkgs_to_upgrade
@ -3074,16 +3048,19 @@ def main(options, rootdir="/"):
# return 1 # return 1
try: try:
kysec_pre_upgrade()
res = run(options, rootdir, logfile_dpkg) res = run(options, rootdir, logfile_dpkg)
kysec_post_upgrade()
logging.info("result:%s,%s"%(res.success,res.result_str)) logging.info("result:%s,%s"%(res.success,res.result_str))
release = '' release = ''
version = '' version = ''
os_release_info = ReadOsRelease('/etc/os-release') os_release_info = ReadOsRelease('/etc/os-release')
if 'KYLIN_RELEASE_ID' in os_release_info: if 'KYLIN_RELEASE_ID' in os_release_info:
release = os_release_info['KYLIN_RELEASE_ID'] release = os_release_info['KYLIN_RELEASE_ID']
#version = ReadValueFromFile(VERSION_FILE,'SYSTEM','version')
version = get_default_version() version = get_default_version()
logging.debug("release:%s,version:%s"%(release,version)) logging.debug("release:%s,version:%s"%(release,version))
if options.install_only: if options.install_only or options.download_and_install:
#history record #history record
history = {} history = {}
date = time.strftime("%Y-%m-%d %H:%M:%S") date = time.strftime("%Y-%m-%d %H:%M:%S")
@ -3105,18 +3082,20 @@ def main(options, rootdir="/"):
UpdateInfos.update({"status":1}) UpdateInfos.update({"status":1})
UpdateInfos.update({"errorCode":"cache commit error"}) UpdateInfos.update({"errorCode":"cache commit error"})
if res.success and len(res.pkgs) > 0 : if res.success and len(res.pkgs) > 0 :
if res.result_str == "total_install": #if res.result_str == "total_install":
# with open(TIME_STAMP,'w') as f: # with open(TIME_STAMP,'w') as f:
# f.write(time.time()) # f.write(time.time())
config=configparser.ConfigParser(allow_no_value=True) config=configparser.ConfigParser(allow_no_value=True)
config.read(KYLIN_VERSION_FILE) config.read(KYLIN_VERSION_FILE)
config.set("SYSTEM","os_version",release) config.set("SYSTEM","os_version",release)
config.set("SYSTEM","update_version",version) config.set("SYSTEM","update_version",version)
with open(KYLIN_VERSION_FILE,'w') as f: with open(KYLIN_VERSION_FILE,'w') as f:
config.write(f) config.write(f)
kylin_system_updater.InsertUpgradeHistory(history) # kylin_system_updater.SetConfigValue("SYSTEM","os_version",release)
json_file = json.dumps(UpdateInfos.copy()) # kylin_system_updater.SetConfigValue("SYSTEM","update_version",original_version)
kylin_system_updater.DataBackendCollect("UpdateInfos",json_file) kylin_system_updater.InsertUpgradeHistory(history)
json_file = json.dumps(UpdateInfos.copy())
kylin_system_updater.DataBackendCollect("UpdateInfos",json_file)
elif not res.success: elif not res.success:
errorlist = kylin_system_updater.DumpInstallErrorRecord() errorlist = kylin_system_updater.DumpInstallErrorRecord()
errorlist.append("cache commit error") errorlist.append("cache commit error")
@ -3134,33 +3113,33 @@ def main(options, rootdir="/"):
logging.info("no pkgs to install") logging.info("no pkgs to install")
if 'PROJECT_CODENAME' in os_release_info: if 'PROJECT_CODENAME' in os_release_info:
if os_release_info['PROJECT_CODENAME']=='V10SP1-edu': if os_release_info['PROJECT_CODENAME']=='V10SP1-edu':
if 'SUB_PROJECT_CODENAME' in os_release_info: if 'SUB_PROJECT_CODENAME' in os_release_info:
if os_release_info['SUB_PROJECT_CODENAME']=='mavis': if os_release_info['SUB_PROJECT_CODENAME']=='mavis':
localtime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time())) localtime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))
config_to_result = configparser.ConfigParser(allow_no_value=True) config_to_result = configparser.ConfigParser(allow_no_value=True)
config_to_result.add_section("OTA") config_to_result.add_section("OTA")
config_to_result.set("OTA","time",localtime) config_to_result.set("OTA","time",localtime)
config_to_result.set("OTA","version","1.0") config_to_result.set("OTA","version","1.0")
config_to_result.set("OTA","upgrade","0") config_to_result.set("OTA","upgrade","0")
config_to_result.set("OTA","status","failed") config_to_result.set("OTA","status","failed")
if res.success: if res.success:
if options.mode == 'shutdown': if options.mode == 'shutdown':
config_to_result.set("OTA","status","success") config_to_result.set("OTA","status","success")
if len(res.pkgs) > 0 : if len(res.pkgs) > 0 :
config_to_result.set("OTA","upgrade","1") config_to_result.set("OTA","upgrade","1")
if not os.path.exists(OTA_RESULT_FILE_PATH): if not os.path.exists(OTA_RESULT_FILE_PATH):
os.makedirs(OTA_RESULT_FILE_PATH) os.makedirs(OTA_RESULT_FILE_PATH)
# os.chmod(OTA_RESULT_FILE_PATH,stat.S_IRUSR|stat.S_IWUSR|stat.S_IWGRP|stat.S_IRGRP|stat.S_IWOTH|stat.S_IROTH) # os.chmod(OTA_RESULT_FILE_PATH,stat.S_IRUSR|stat.S_IWUSR|stat.S_IWGRP|stat.S_IRGRP|stat.S_IWOTH|stat.S_IROTH)
if not os.path.exists(OTA_RESULT_FILE): if not os.path.exists(OTA_RESULT_FILE):
f = open(OTA_RESULT_FILE,'w') f = open(OTA_RESULT_FILE,'w')
f.close() f.close()
with open(OTA_RESULT_FILE,"w+") as f: with open(OTA_RESULT_FILE,"w+") as f:
config_to_result.write(f) config_to_result.write(f)
subprocess.Popen("chmod -R 777 %s"%(OTA_RESULT_FILE_PATH),shell=True) subprocess.Popen("chmod -R 777 %s"%(OTA_RESULT_FILE_PATH),shell=True)
# os.chmod(OTA_RESULT_FILE,stat.S_IRUSR|stat.S_IWUSR|stat.S_IWGRP|stat.S_IRGRP|stat.S_IWOTH|stat.S_IROTH) # os.chmod(OTA_RESULT_FILE,stat.S_IRUSR|stat.S_IWUSR|stat.S_IWGRP|stat.S_IRGRP|stat.S_IWOTH|stat.S_IROTH)
# os.chmod(OTA_RESULT_FILE,stat.S_IRWXU|stat.S_IRWXG|stat.S_IRWXO) # os.chmod(OTA_RESULT_FILE,stat.S_IRWXU|stat.S_IRWXG|stat.S_IRWXO)
# WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle") # WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle")
@ -3197,6 +3176,8 @@ def main(options, rootdir="/"):
except Exception as e: except Exception as e:
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle") WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle")
logging.error(e) logging.error(e)
if options.install_only:
reboot_if_needed()
# logger = logging.getLogger() # logger = logging.getLogger()
# logger.exception(_("An error occurred: %s"), e) # logger.exception(_("An error occurred: %s"), e)
# log_content = get_dpkg_log_content(logfile_dpkg, # log_content = get_dpkg_log_content(logfile_dpkg,
@ -3376,7 +3357,7 @@ def run(options, # type: Options
False, _("Apt returned an error, exiting")) False, _("Apt returned an error, exiting"))
if cache._depcache.broken_count > 0: if cache._depcache.broken_count > 0:
#print(_("Cache has broken packages, exiting")) print(_("Cache has broken packages, exiting"))
logging.error(_("Cache has broken packages, exiting")) logging.error(_("Cache has broken packages, exiting"))
return UnattendedUpgradesResult( return UnattendedUpgradesResult(
False, _("Cache has broken packages, exiting")) False, _("Cache has broken packages, exiting"))
@ -3400,11 +3381,14 @@ def run(options, # type: Options
# find out about the packages that are upgradable (in an allowed_origin) # find out about the packages that are upgradable (in an allowed_origin)
pkgs_to_upgrade = calculate_upgradable_pkgs(cache, options,white_list_with_version) pkgs_to_upgrade = calculate_upgradable_pkgs(cache, options,white_list_with_version)
if options.install_only or options.download_and_install:
if (len(pkgs_to_upgrade)<len(white_list_with_version)):
logging.warning("some pkgs failed in sanity check")
return UnattendedUpgradesResult(False,"sanity check failed")
pkgs_to_upgrade.sort(key=lambda p: p.name) pkgs_to_upgrade.sort(key=lambda p: p.name)
pkgs = [pkg.name for pkg in pkgs_to_upgrade] pkgs = [pkg.name for pkg in pkgs_to_upgrade]
logging.debug("%d pkgs that look like they should be upgraded or installed: %s" logging.debug("pkgs that look like they should be upgraded or installed: %s"
% (len(pkgs),"\n".join(pkgs))) % "\n".join(pkgs))
# FIXME: make this into a ContextManager # FIXME: make this into a ContextManager
# stop being nice # stop being nice
@ -3448,6 +3432,7 @@ def run(options, # type: Options
logging.debug("%d local,%d remote"%(fetcher_statistics.local_pkg_amount,fetcher_statistics.remote_pkg_amount)) logging.debug("%d local,%d remote"%(fetcher_statistics.local_pkg_amount,fetcher_statistics.remote_pkg_amount))
if options.install_only: if options.install_only:
if options.mode == 'shutdown': if options.mode == 'shutdown':
if kylin_system_updater.GetConfigValue('InstallMode','shutdown_install'): if kylin_system_updater.GetConfigValue('InstallMode','shutdown_install'):
pass pass
@ -3464,7 +3449,7 @@ def run(options, # type: Options
apt_pkg.pkgsystem_unlock() apt_pkg.pkgsystem_unlock()
except SystemError: except SystemError:
logging.error(_("lock release failed")) logging.error(_("lock release failed"))
return UnattendedUpgradesResult(True,_("no local pkgs to install")) return UnattendedUpgradesResult(False,_("no local pkgs to install"))
elif fetcher_statistics.remote_pkg_amount >0: elif fetcher_statistics.remote_pkg_amount >0:
logging.warning("there're pkgs to download") logging.warning("there're pkgs to download")
try: try:
@ -3494,8 +3479,15 @@ def run(options, # type: Options
if os_release_info['SUB_PROJECT_CODENAME']=='mavis': if os_release_info['SUB_PROJECT_CODENAME']=='mavis':
pass pass
else: else:
logging.info("neeed backup") logging.info("need backup")
#Backup() backup_result = False
backup_result = Backup()
if (backup_result):
pass
else:
logging.debug("backup failed...")
return UnattendedUpgradesResult(False,"backup failed")
# do install # do install
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","install") WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","install")
#send install start msg to notify #send install start msg to notify
@ -3517,11 +3509,13 @@ def run(options, # type: Options
% (cache._depcache.inst_count, % (cache._depcache.inst_count,
cache._depcache.del_count, cache._depcache.del_count,
cache._depcache.broken_count)) cache._depcache.broken_count))
logging.info("shutdown safe manager")
pkg_install_success = do_install(cache, pkg_install_success = do_install(cache,
pkgs, pkgs,
options, options,
logfile_dpkg) logfile_dpkg)
logging.info("reset safe manager")
# unLockedEnableShutdown() # unLockedEnableShutdown()
inhibitshutdownlock.unlock() inhibitshutdownlock.unlock()
@ -3575,7 +3569,7 @@ def run(options, # type: Options
break break
#fetcher_statistics.ResetFetcher(fetcher) #fetcher_statistics.ResetFetcher(fetcher)
#fetcher_statistics.GetAquireStatisticsOfPkgs() #fetcher_statistics.GetAquireStatisticsOfPkgs()
insmod = ReadValueFromFile("/var/lib/unattended-upgrades/unattended-upgrades-policy.conf","autoUpgradePolicy","installmode") insmod = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH,"autoUpgradePolicy","installmode")
if fetcher_statistics.incomplete_pkg_amount == 0 and len(pkgs_to_upgrade) > 0: if fetcher_statistics.incomplete_pkg_amount == 0 and len(pkgs_to_upgrade) > 0:
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis': if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
docker_image_fetch_result = 0 docker_image_fetch_result = 0
@ -3605,12 +3599,87 @@ def run(options, # type: Options
except SystemError: except SystemError:
logging.error(_("lock release failed")) logging.error(_("lock release failed"))
return UnattendedUpgradesResult(True,_("all pkgs downloaded")) return UnattendedUpgradesResult(True,_("all pkgs downloaded"))
else: elif fetcher_statistics.incomplete_pkg_amount > 0 and len(pkgs_to_upgrade) > 0:
try: try:
apt_pkg.pkgsystem_unlock() apt_pkg.pkgsystem_unlock()
except SystemError: except SystemError:
logging.error(_("lock release failed")) logging.error(_("lock release failed"))
return UnattendedUpgradesResult(False,_("some pkgs incompletely fetched")) return UnattendedUpgradesResult(False,_("some pkgs incompletely fetched"))
else:
try:
apt_pkg.pkgsystem_unlock()
except SystemError:
logging.error(_("lock release failed"))
return UnattendedUpgradesResult(True,_("all pkgs downloaded"))
elif options.download_and_install:
if len(pkgs)==0:
logging.info("no pkgs to install")
return UnattendedUpgradesResult(True,_("there're no pkgs to install"))
if fetcher_statistics.remote_pkg_amount>0:
pass
else:
logging.info("no pkgs need to download")
#return UnattendedUpgradesResult(True,_("there're no pkgs to download"))
retry_times=10
if retry_times<0:
retry_times = 1
while retry_times >0:
try:
res = fetcher.run()
logging.debug("fetch.run() result: %s", res)
except SystemError as e:
logging.error("fetch.run() result: %s", e)
fetcher_statistics.ResetFetcher(fetcher)
fetcher_statistics.GetAquireStatisticsOfPkgs()
logging.debug("incomplete download pkg number:%d"%fetcher_statistics.incomplete_pkg_amount)
retry_times-=1
if fetcher_statistics.incomplete_pkg_amount >0:
logging.debug("%d incomplete pkgs,%d try times left")
fetcher.shutdown()
try:
pm.get_archives(fetcher, list, recs)
except SystemError as e:
logging.error(_("GetArchives() failed: %s"), e)
else:
break
pkg_install_success = True
install_result = ''
backup_result = False
backup_result = Backup()
if (backup_result):
pass
else:
logging.debug("backup failed...")
return UnattendedUpgradesResult(False,"backup failed")
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","install")
inhibitshutdownlock.lock()
logging.debug("InstCount=%i DelCount=%i BrokenCount=%i"
% (cache._depcache.inst_count,
cache._depcache.del_count,
cache._depcache.broken_count))
logging.info("shutdown safe manager")
pkg_install_success = do_install(cache,
pkgs,
options,
logfile_dpkg)
logging.info("reset safe manager")
# unLockedEnableShutdown()
inhibitshutdownlock.unlock()
subprocess.Popen('dbus-send --system --type=signal / com.kylin.install.notification.InstallFinish',shell=True)
if pkg_install_success:
clean_downloaded_packages(fetcher)
kylin_system_updater.CheckRebootRequired("unattended-upgrades")
logging.debug("pkg number:%d,pkg in whitelist number:%d"%(len(pkgs),len(white_list_with_version)))
if len(pkgs) == len(white_list_with_version):
install_result = "total_install"
else:
install_result = "partial_install"
logging.debug("install result:%s"%install_result)
try:
apt_pkg.pkgsystem_unlock()
except SystemError:
logging.error(_("lock release failed"))
return UnattendedUpgradesResult(pkg_install_success,install_result,pkgs)
else: else:
try: try:
apt_pkg.pkgsystem_unlock() apt_pkg.pkgsystem_unlock()
@ -3910,6 +3979,7 @@ class Options:
def __init__(self): def __init__(self):
self.download_only = False self.download_only = False
self.install_only = False self.install_only = False
self.download_and_install = False
self.dry_run = False self.dry_run = False
self.debug = False self.debug = False
self.apt_debug = False self.apt_debug = False
@ -3917,6 +3987,7 @@ class Options:
self.minimal_upgrade_steps = False self.minimal_upgrade_steps = False
self.mode = None self.mode = None
shutdown_lock = -1 shutdown_lock = -1
if __name__ == "__main__": if __name__ == "__main__":
@ -3970,6 +4041,9 @@ if __name__ == "__main__":
parser.add_option("", "--install-only", parser.add_option("", "--install-only",
action="store_true", default=False, action="store_true", default=False,
help=_("Only install, do not even try to download.")) help=_("Only install, do not even try to download."))
parser.add_option("", "--download-and-install",
action="store_true", default=False,
help=_("Download and Install."))
parser.add_option("", "--minimal-upgrade-steps", parser.add_option("", "--minimal-upgrade-steps",
action="store_true", default=minimal_steps_default, action="store_true", default=minimal_steps_default,
help=_("Upgrade in minimal steps (and allow " help=_("Upgrade in minimal steps (and allow "
@ -4027,13 +4101,27 @@ if __name__ == "__main__":
pass pass
# setup logging # setup logging
_setup_logging(options,logfile) # _setup_logging(options,logfile)
logging.basicConfig(format='%(asctime)s-%(name)s-%(levelname)s-%(message)s',level=logging.DEBUG,filename=logfile)
# logging.basicConfig()
# file_handler = logging.FileHandler(filename=logfile)
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setLevel(logging.INFO)
# formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# file_handler.setFormatter(formatter)
logger=logging.getLogger()
logger.setLevel(logging.DEBUG)
# logger.addHandler(file_handler)
logger.addHandler(stdout_handler)
#get os release info #get os release info
os_release_info = ReadOsRelease('/etc/os-release') os_release_info = ReadOsRelease('/etc/os-release')
#print(os_release_info) #print(os_release_info)
config_manager = ConfigFileManager(CONFIG_FILE_ROOT_PATH) config_manager = ConfigFileManager(CONFIG_FILE_ROOT_PATH)
login_manager = LoginManager() login_manager = LoginManager()
kylin_system_updater = KylinSystemUpdater() kylin_system_updater = KylinSystemUpdater()
''' '''
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis': if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
pass pass
@ -4065,6 +4153,9 @@ if __name__ == "__main__":
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","download") WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","download")
elif options.install_only: elif options.install_only:
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","preinstall") WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","preinstall")
elif options.download_and_install:
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","preinstall")
# run the main code # run the main code
install_start_time = datetime.datetime.now().replace(microsecond=0) install_start_time = datetime.datetime.now().replace(microsecond=0)
logging.info("unattended-upgrades start time:%s"%install_start_time) logging.info("unattended-upgrades start time:%s"%install_start_time)

View File

@ -26,20 +26,22 @@
# #
import copy import copy
# from multiprocessing.connection import wait
# from concurrent.futures import ThreadPoolExecutor
# from stat import filemode
import dbus import dbus
import signal import signal
import sys import sys
import time import time
import datetime import datetime
import logging import logging
import logging.handlers
import gettext import gettext
import subprocess import subprocess
import os.path import os.path
import os import os
import configparser import configparser
import psutil import psutil
from pytz import timezone
# for dbus signal handling # for dbus signal handling
try: try:
from dbus.mainloop.glib import DBusGMainLoop from dbus.mainloop.glib import DBusGMainLoop
@ -49,7 +51,7 @@ except ImportError:
from optparse import OptionParser, Values from optparse import OptionParser, Values
Values # pyflakes Values # pyflakes
from gettext import gettext as _ from gettext import gettext as _, install
from threading import Event from threading import Event
from enum import IntEnum, Enum from enum import IntEnum, Enum
from apscheduler.schedulers.blocking import BlockingScheduler from apscheduler.schedulers.blocking import BlockingScheduler
@ -85,7 +87,6 @@ AUTO_UPGRADE_POLICY_OPTION_UPGRADE_INTERVAL = "upgradeInverval"
INTERVAL_DOWN_INSTALL = 120 # 下载安装的间隔 分钟 INTERVAL_DOWN_INSTALL = 120 # 下载安装的间隔 分钟
INSTALL_RANDOM = 5 # 安装时间随机数范围0-INSTALL_RANDOM 分钟 INSTALL_RANDOM = 5 # 安装时间随机数范围0-INSTALL_RANDOM 分钟
DOWNLOAD_RANDOM = 180 # 下载时间随机数范围0-DOWNLOAD_RANDOM 分钟 DOWNLOAD_RANDOM = 180 # 下载时间随机数范围0-DOWNLOAD_RANDOM 分钟
PREDOWNLOAD_RANDOM = 180
class FeatureSwitch(Enum): class FeatureSwitch(Enum):
ON = 'on' ON = 'on'
@ -115,6 +116,60 @@ UNATTENDED_UPGRADE_TIMESTAMP = "/var/lib/unattended-upgrades/unattended-upgrades
flag_file_list = ["/var/lib/unattended-upgrades/OTA_PKGS_TO_INSTALL",\ flag_file_list = ["/var/lib/unattended-upgrades/OTA_PKGS_TO_INSTALL",\
"/var/lib/kylin-auto-upgrade/kylin-autoupgrade.conf","/tmp/notify.pid"] "/var/lib/kylin-auto-upgrade/kylin-autoupgrade.conf","/tmp/notify.pid"]
def _setup_logging(options,logfile):
# ensure this is run only once
if len(logging.root.handlers) > 0:
return None
# init the logging
# logdir = _get_logdir()
# logfile = os.path.join(
# logdir,
# apt_pkg.config.find(
# "Unattended-Upgrade::LogFile",
# # COMPAT only
# apt_pkg.config.find("APT::UnattendedUpgrades::LogFile",
# "unattended-upgrades.log")))
# if not options.dry_run and not os.path.exists(logdir):
# os.makedirs(logdir)
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(levelname)s %(message)s',
filename=logfile)
# additional logging
logger = logging.getLogger()
# mem_log = StringIO()
# if options.apt_debug:
# apt_pkg.config.set("Debug::pkgProblemResolver", "1")
# apt_pkg.config.set("Debug::pkgDepCache::AutoInstall", "1")
if options.debug:
logger.setLevel(logging.DEBUG)
# stdout_handler = logging.StreamHandler(sys.stdout)
# logger.addHandler(stdout_handler)
elif options.verbose:
logger.setLevel(logging.INFO)
logging.getLogger('apscheduler').setLevel(logging.DEBUG)
stdout_handler = logging.StreamHandler(sys.stdout)
logger.addHandler(stdout_handler)
def get_random_time(time_interval):
try:
start_time = datetime.datetime.strptime(time_interval.split("-")[0],"%H:%M")
end_time = datetime.datetime.strptime(time_interval.split("-")[1],"%H:%M")
now = datetime.datetime.now()
start=datetime.datetime(now.year,now.month,now.day,start_time.hour,start_time.minute,0,0)
end=datetime.datetime(now.year,now.month,now.day,end_time.hour,end_time.minute,0,0)
time_diff = int((end-start).total_seconds())
if time_diff<0:
time_diff=time_diff+86400
delta = random.randint(0,time_diff)
actual_time = start+datetime.timedelta(seconds=delta)
return actual_time
except Exception as e:
logging.error(e)
def reload_options_config(): def reload_options_config():
#添加默认保留旧配置 #添加默认保留旧配置
apt_pkg.config["DPkg::Options::"] = "--force-confold" apt_pkg.config["DPkg::Options::"] = "--force-confold"
@ -178,6 +233,8 @@ def ReadOsRelease(file):
osreleasedict.update({ls[0]:ls[1].strip('"')}) osreleasedict.update({ls[0]:ls[1].strip('"')})
except Exception as e: except Exception as e:
pass pass
if 'PROJECT_CODENAME' not in osreleasedict.keys():
osreleasedict.update({'PROJECT_CODENAME':''})
if 'SUB_PROJECT_CODENAME' not in osreleasedict.keys(): if 'SUB_PROJECT_CODENAME' not in osreleasedict.keys():
osreleasedict.update({'SUB_PROJECT_CODENAME':''}) osreleasedict.update({'SUB_PROJECT_CODENAME':''})
return osreleasedict return osreleasedict
@ -196,6 +253,7 @@ def FindRuningUnattendedUpgrades():
def ReadValueFromFile(file,section,option): def ReadValueFromFile(file,section,option):
config=configparser.ConfigParser(allow_no_value=True) config=configparser.ConfigParser(allow_no_value=True)
config.optionxform = str
try: try:
config.read(file) config.read(file)
value = config[section][option] value = config[section][option]
@ -205,6 +263,7 @@ def ReadValueFromFile(file,section,option):
def WriteValueToFile(file,section,option,value): def WriteValueToFile(file,section,option,value):
config=configparser.ConfigParser(allow_no_value=True) config=configparser.ConfigParser(allow_no_value=True)
config.optionxform = str
config.add_section(section) config.add_section(section)
config.set(section,option,value) config.set(section,option,value)
config.write(open(file,"w")) config.write(open(file,"w"))
@ -217,68 +276,6 @@ def clean_flag_files(filelist):
def init(): def init():
if not os.path.exists(NOTIFICATION_PIPE): if not os.path.exists(NOTIFICATION_PIPE):
os.mkfifo(NOTIFICATION_PIPE) os.mkfifo(NOTIFICATION_PIPE)
def get_random_time(stime,random_range):
now = datetime.datetime.now()
delta = random.randint(0,random_range)
actual_time = now + datetime.timedelta(minutes=delta)
try:
start_time = datetime.datetime.strptime(stime,"%H:%M")
start=datetime.datetime(now.year,now.month,now.day,start_time.hour,start_time.minute,0,0)
actual_time = start+datetime.timedelta(minutes=delta)
except Exception as e:
logging.error(e)
return actual_time
def task(task):
env = copy.copy(os.environ)
cmd = "date"
if task in ["predownload","download"]:
cmd = "kylin-unattended-upgrade --download-only"
elif task == "install":
cmd = "kylin-unattended-upgrade --install-only --mode=timing"
elif task == "download_and_install":
cmd = "kylin-unattended-upgrade --download-only&&kylin-unattended-upgrade --install-only --mode=timing"
#do not check updgrade period when download and install
else:
pass
ret = subprocess.run([cmd], shell=True,env=env)
logging.debug("task:%s return code:%d"%(task,ret.returncode))
return ret.returncode
def background_scheduler_init(background_scheduler):
background_scheduler.start()
random_time = get_random_time(autoupgradepolicy.GetOptionValue('downloadTime'),DOWNLOAD_RANDOM)
background_scheduler.add_job(task,'cron', args=['download'],id='download', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
random_time = random_time + datetime.timedelta(minutes=INTERVAL_DOWN_INSTALL)
background_scheduler.add_job(task,'cron', args=['install'],id='install', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
random_time = get_random_time(autoupgradepolicy.GetOptionValue('preDownloadTime'),PREDOWNLOAD_RANDOM)
background_scheduler.add_job(task,'cron', args=['predownload'],id='predownload', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
if autoupgradepolicy.GetOptionValue('autoUpgradeState') == 'on':
if autoupgradepolicy.GetOptionValue('downloadMode') != 'timing':
background_scheduler.pause_job('download')
if autoupgradepolicy.GetOptionValue('installMode') != 'timing':
background_scheduler.pause_job('install')
else:
background_scheduler.pause_job('download')
background_scheduler.pause_job('install')
if autoupgradepolicy.GetOptionValue('preDownload') != 'on':
background_scheduler.pause_job('predownload')
joblist = background_scheduler.get_jobs()
for job in joblist:
logging.debug("job:%s,next run time:%s"%(job.id,job.next_run_time))
''' '''
def do_usplash(msg): def do_usplash(msg):
# type: (str) -> None # type: (str) -> None
@ -392,6 +389,109 @@ class TimerThread(threading.Thread):
def run(self): def run(self):
self.scheduler.start() self.scheduler.start()
def empty_task():
pass
def task(task):
env = copy.copy(os.environ)
last_run_time = '2022-01-01 00:00:00'
config=configparser.ConfigParser(allow_no_value=True)
config.optionxform = str
config.read(UNATTENDED_UPGRADE_TIMESTAMP)
last_run_time = config['timestamp'][task]
logging.debug("%s timestamp:%s,"%(task,last_run_time))
last_run_date = datetime.datetime.strptime(last_run_time,"%Y-%m-%d %H:%M:%S")
now = datetime.datetime.now()
duration = (now - last_run_date).days
update_interval = int(autoupgradepolicy.GetOptionValue('updateDays'))
cmd = "date"
if task in ["predownload","download"]:
cmd = "kylin-unattended-upgrade --download-only"
elif task == "install":
cmd = "kylin-unattended-upgrade --install-only --mode=timing"
elif task == "download_and_install":
cmd = "kylin-unattended-upgrade --download-and-install"
#do not check updgrade period when download and install
update_interval = 0
else:
pass
if duration < update_interval:
logging.info("not long enough from last run")
return
ret = subprocess.run([cmd], shell=True,env=env)
logging.debug("task:%s return code:%d"%(task,ret.returncode))
if ret.returncode == 0:
now = datetime.datetime.now()
config['timestamp'][task] = now.strftime("%Y-%m-%d %H:%M:%S")
with open(UNATTENDED_UPGRADE_TIMESTAMP,"w") as f:
config.write(f)
logging.info("successful run,new time stamp:%s"%now.strftime("%Y-%m-%d %H:%M:%S"))
return ret.returncode
def timing_predownload():
env = copy.copy(os.environ)
logging.debug("starting unattended-upgrades in pre-download mode")
pre_download_ret = subprocess.run(["kylin-unattended-upgrade","--download-only"], env=env)
if pre_download_ret.returncode == 0:
logging.debug("kylin-unattended-upgrade download success.")
else:
logging.debug("kylin-unattended-upgrade download %d .",pre_download_ret.returncode)
def timing_download():
env = copy.copy(os.environ)
logging.debug("starting unattended-upgrades in timing download mode")
timing_download_ret = subprocess.run(["kylin-unattended-upgrade","--download-only"], env=env)
if timing_download_ret.returncode == 0:
logging.debug("kylin-unattended-upgrade download success.")
else:
logging.debug("kylin-unattended-upgrade download %d .",timing_download_ret.returncode)
def timing_install():
env = copy.copy(os.environ)
logging.debug("starting unattended-upgrades in timing install mode")
timing_install_ret = subprocess.run(["kylin-unattended-upgrade","--install-only","--mode=timing"], env=env)
if timing_install_ret.returncode == 0:
logging.debug("kylin-unattended-upgrade install success.")
else:
logging.debug("kylin-unattended-upgrade install %d .",timing_install_ret.returncode)
def background_scheduler_init(background_scheduler):
background_scheduler.start()
random_time = get_random_time(autoupgradepolicy.GetOptionValue('downloadTime'))
background_scheduler.add_job(task,'cron', args=['download'],id='download', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
instime = autoupgradepolicy.GetOptionValue('installTime')
# random_time = get_random_time("%s-%s"%(instime,instime))
random_time = get_random_time(instime)
background_scheduler.add_job(task,'cron', args=['install'],id='install', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
random_time = get_random_time(autoupgradepolicy.GetOptionValue('preDownloadTime'))
background_scheduler.add_job(task,'cron', args=['predownload'],id='predownload', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
if autoupgradepolicy.GetOptionValue('autoUpgradeState') == 'on':
if autoupgradepolicy.GetOptionValue('downloadMode') != 'timing':
background_scheduler.pause_job('download')
if autoupgradepolicy.GetOptionValue('installMode') != 'timing':
background_scheduler.pause_job('install')
else:
background_scheduler.pause_job('download')
background_scheduler.pause_job('install')
if autoupgradepolicy.GetOptionValue('preDownload') != 'on':
background_scheduler.pause_job('predownload')
joblist = background_scheduler.get_jobs()
for job in joblist:
logging.debug("job:%s,next run time:%s"%(job.id,job.next_run_time))
class KylinSystemUpdater: class KylinSystemUpdater:
def __init__(self) -> None: def __init__(self) -> None:
DBusGMainLoop(set_as_default=True) DBusGMainLoop(set_as_default=True)
@ -406,6 +506,7 @@ class KylinSystemUpdater:
def SetConfigValue(self,section,option,value): def SetConfigValue(self,section,option,value):
return self.update_interface.SetConfigValue(section,option,value) return self.update_interface.SetConfigValue(section,option,value)
class AutoUpgradePolicy(): class AutoUpgradePolicy():
def __init__(self) -> None: def __init__(self) -> None:
self.autoupgradepolicy = {} self.autoupgradepolicy = {}
@ -427,31 +528,75 @@ class AutoUpgradePolicy():
except Exception: except Exception:
return '' return ''
def reload_config(self): def ExecutePolicy(self,property,value):
if os.path.exists(UNATTENDED_UPGRADE_POLICY_FILE_PATH): if property == 'autoUpgradeState':
config=configparser.ConfigParser(allow_no_value=True) if value == 'off':
config.optionxform = str background_scheduler.pause_job('download')
config.read(UNATTENDED_UPGRADE_POLICY_FILE_PATH) background_scheduler.pause_job('install')
for option in config.options('autoUpgradePolicy'): elif value == 'on':
self.autoupgradepolicy.update({option:config['autoUpgradePolicy'][option]}) if self.autoupgradepolicy['downloadMode'] == 'timing':
for key in self.autoupgradepolicy.keys(): background_scheduler.resume_job('download')
logging.debug("%s:%s"%(key,self.autoupgradepolicy[key])) if self.autoupgradepolicy['installMode'] == 'timing':
background_scheduler.resume_job('install')
else:
pass
elif property == 'downloadMode':
if value == 'timing':
if self.autoupgradepolicy['autoUpgradeState'] == 'on':
background_scheduler.resume_job('download')
elif value == 'manual':
background_scheduler.pause_job('download')
else:
pass
elif property == 'downloadTime':
if self.autoupgradepolicy['autoUpgradeState'] == 'on' and \
self.autoupgradepolicy['downloadMode'] == 'timing':
random_time = get_random_time(value)
background_scheduler.reschedule_job('download',trigger='cron',hour=random_time.hour,minute = random_time.minute)
elif property == 'installMode':
if value == 'timing':
if self.autoupgradepolicy['autoUpgradeState'] == 'on':
background_scheduler.resume_job('install')
elif value == 'manual':
background_scheduler.pause_job('install')
elif value == 'bshutdown':
background_scheduler.pause_job('install')
else:
pass
elif property == 'installTime':
if self.autoupgradepolicy['autoUpgradeState'] == 'on' and \
self.autoupgradepolicy['installMode'] == 'timing':
random_time = get_random_time(value)
background_scheduler.reschedule_job('install',trigger='cron',hour=random_time.hour,minute = random_time.minute)
elif property == 'preDownload':
if value == 'off':
background_scheduler.pause_job('predownload')
elif value == 'on':
background_scheduler.resume_job('predownload')
else:
pass
elif property == 'preDownloadTime':
if self.autoupgradepolicy['preDownload'] == 'on':
random_time = get_random_time(value)
background_scheduler.reschedule_job('predownload',trigger='cron',hour=random_time.hour,minute = random_time.minute)
else:
pass
class UnattendedUpgradesShutdown(): class UnattendedUpgradesShutdown():
# 加载配置文件 unattended-upgrades-policy.conf # 加载配置文件 unattended-upgrades-policy.conf
'''
def loadcfg(self): def loadcfg(self):
if os.path.exists(UNATTENDED_UPGRADE_POLICY_FILE_PATH): if os.path.isfile(UNATTENDED_UPGRADE_POLICY_FILE_PATH):
self.preDownload = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_PREDOWNLOAD) self.preDownload = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_PREDOWNLOAD)
self.autoUpgrade = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_AUTOUPGRADE) self.autoUpgrade = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_AUTOUPGRADE)
self.download_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_MODE) self.download_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_MODE)
self.install_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_INSTALL_MODE) self.install_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_INSTALL_MODE)
download_time = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_TIME) download_time = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_TIME)
# self.download_random = int(kylin_system_updater.GetConfigValue('AutoUpgradeConfig','downloadRandom')[1]) self.download_random = int(kylin_system_updater.GetConfigValue('AutoUpgradeConfig','downloadRandom')[1])
# self.upgrade_interval = int(kylin_system_updater.GetConfigValue('AutoUpgradeConfig','upgradeInterval')[1]) self.upgrade_interval = int(kylin_system_updater.GetConfigValue('AutoUpgradeConfig','upgradeInterval')[1])
# logging.info("download random:%s,upgrade interval:%s"%(self.download_random,self.upgrade_interval)) logging.info("download random:%s,upgrade interval:%s"%(self.download_random,self.upgrade_interval))
# upgradeInterval = int(ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, 'upgradeInverval')) # upgradeInterval = int(ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, 'upgradeInverval'))
'''
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis': if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
self.download_time['h'] = 10 self.download_time['h'] = 10
self.download_time['m'] = 0 self.download_time['m'] = 0
@ -460,13 +605,11 @@ class UnattendedUpgradesShutdown():
self.download_time_r['h'], self.download_time_r['m'],self.preDownload, self.autoUpgrade, \ self.download_time_r['h'], self.download_time_r['m'],self.preDownload, self.autoUpgrade, \
self.download_mode, self.install_mode) self.download_mode, self.install_mode)
return return
'''
timelist = download_time.strip().split(':') timelist = download_time.strip().split(':')
if len(timelist) != TimeElement.TIME_NUM: if len(timelist) != TimeElement.TIME_NUM:
logging.debug("unattended-upgrades-policy.conf time err %s",download_time) logging.debug("unattended-upgrades-policy.conf time err %s",download_time)
return return
# 检查 传入时间 安全性 # 检查 传入时间 安全性
try: try:
tmphour = int(timelist[TimeElement.TIME_HOUR]) tmphour = int(timelist[TimeElement.TIME_HOUR])
@ -490,8 +633,7 @@ class UnattendedUpgradesShutdown():
self.preDownload, self.autoUpgrade, self.download_mode, self.install_mode) self.preDownload, self.autoUpgrade, self.download_mode, self.install_mode)
else: else:
logging.debug("unattended-upgrades-policy.conf not exist") logging.debug("unattended-upgrades-policy.conf not exist")
return
'''
def __init__(self, options): def __init__(self, options):
# type: (Values) -> None # type: (Values) -> None
self.options = options self.options = options
@ -518,8 +660,9 @@ class UnattendedUpgradesShutdown():
self.download_job = None self.download_job = None
self.install_job = None self.install_job = None
self.startup_download_job = None self.startup_download_job = None
self.scheduler = BlockingScheduler(timezone = "Asia/Shanghai") self.scheduler = BlockingScheduler()
''' '''
try: try:
hasattr(GLib, "MainLoop") hasattr(GLib, "MainLoop")
DBusGMainLoop(set_as_default=True) DBusGMainLoop(set_as_default=True)
@ -534,15 +677,26 @@ class UnattendedUpgradesShutdown():
self.inhibit_lock = None self.inhibit_lock = None
self.logind_proxy = None self.logind_proxy = None
self.update_proxy = None self.update_proxy = None
self.upgrade_strategy_proxy = None
self.wait_period = min(3, self.get_inhibit_max_delay() / 3) self.wait_period = min(3, self.get_inhibit_max_delay() / 3)
self.preparing_for_shutdown = False self.preparing_for_shutdown = False
#self.loadcfg() #self.loadcfg()
def get_upgrade_strategy_proxy(self):
if not self.upgrade_strategy_proxy:
bus = dbus.SystemBus()
self.upgrade_strategy_proxy = bus.get_object('com.kylin.UpgradeStrategies','/com/kylin/UpgradeStrategies')
return self.upgrade_strategy_proxy
def get_upgrade_strategy_interface(self):
self.upgrade_strategy_interface = dbus.Interface(self.upgrade_strategy_proxy,dbus_interface='com.kylin.UpgradeStrategies.interface')
def get_update_proxy(self): def get_update_proxy(self):
if not self.update_proxy: if not self.update_proxy:
bus = dbus.SystemBus() bus = dbus.SystemBus()
self.update_proxy = bus.get_object('com.kylin.systemupgrade','/com/kylin/systemupgrade') self.update_proxy = bus.get_object('com.kylin.systemupgrade','/com/kylin/systemupgrade')
return self.update_proxy return self.update_proxy
def get_update_interface(self): def get_update_interface(self):
self.update_interface = dbus.Interface(self.update_proxy,dbus_interface='com.kylin.systemupgrade.interface') self.update_interface = dbus.Interface(self.update_proxy,dbus_interface='com.kylin.systemupgrade.interface')
@ -593,7 +747,7 @@ class UnattendedUpgradesShutdown():
/ (1000 * 1000)) / (1000 * 1000))
except dbus.exceptions.DBusException: except dbus.exceptions.DBusException:
return 3 return 3
'''
def is_preparing_for_shutdown(self): def is_preparing_for_shutdown(self):
if not self.shutdown_pending: if not self.shutdown_pending:
try: try:
@ -606,7 +760,7 @@ class UnattendedUpgradesShutdown():
except dbus.exceptions.DBusException: except dbus.exceptions.DBusException:
return False return False
return self.shutdown_pending return self.shutdown_pending
'''
def start_iterations(self): def start_iterations(self):
while self.iter(): while self.iter():
time.sleep(1) time.sleep(1)
@ -644,7 +798,7 @@ class UnattendedUpgradesShutdown():
while not self.iter(): while not self.iter():
# TODO iter on sigterm and sighup, too # TODO iter on sigterm and sighup, too
time.sleep(self.wait_period) time.sleep(self.wait_period)
'''
# 定时下载 执行函数 # 定时下载 执行函数
def timing_download(self): def timing_download(self):
env = copy.copy(os.environ) env = copy.copy(os.environ)
@ -659,7 +813,7 @@ class UnattendedUpgradesShutdown():
def timing_install(self): def timing_install(self):
env = copy.copy(os.environ) env = copy.copy(os.environ)
logging.debug("starting unattended-upgrades in timing install mode") logging.debug("starting unattended-upgrades in timing install mode")
timing_install_ret = subprocess.run(["kylin-unattended-upgrade","--install-only","--mode=timing"], env=env) timing_install_ret = subprocess.run(["kylin-unattended-upgrade","--install-only"], env=env)
if timing_install_ret.returncode == 0: if timing_install_ret.returncode == 0:
logging.debug("kylin-unattended-upgrade install success.") logging.debug("kylin-unattended-upgrade install success.")
else: else:
@ -693,7 +847,7 @@ class UnattendedUpgradesShutdown():
if self.install_job is not None: if self.install_job is not None:
self.install_job.resume() self.install_job.resume()
'''
def run(self): def run(self):
""" delay shutdown and wait for PrepareForShutdown or other signals""" """ delay shutdown and wait for PrepareForShutdown or other signals"""
# if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis': # if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
@ -713,7 +867,7 @@ class UnattendedUpgradesShutdown():
"only if it is running") "only if it is running")
self.stop_signal_received.set() self.stop_signal_received.set()
#self.start_iterations() #self.start_iterations()
'''
# fall back to polling without GLib # fall back to polling without GLib
try: try:
hasattr(GLib, "MainLoop") hasattr(GLib, "MainLoop")
@ -721,41 +875,22 @@ class UnattendedUpgradesShutdown():
logging.error("MainLoop Not Found") logging.error("MainLoop Not Found")
#self.run_polling(signal_handler) #self.run_polling(signal_handler)
return return
'''
for sig in (signal.SIGTERM, signal.SIGHUP): for sig in (signal.SIGTERM, signal.SIGHUP):
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, sig, GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, sig,
signal_handler, None, None) signal_handler, None, None)
''' '''
if self.options.wait_for_signal: if self.options.wait_for_signal:
def property_changed_handler(property, value):
logging.debug("property change:%s:%s"%(property,value))
autoupgradepolicy.SetOptionValue(property,value)
autoupgradepolicy.ExecutePolicy(property,value)
joblist = background_scheduler.get_jobs()
for job in joblist:
logging.debug("job:%s,next run time:%s"%(job.id,job.next_run_time))
'''
def change_upgrade_policy_handler(): def change_upgrade_policy_handler():
if os.path.exists(UNATTENDED_UPGRADE_POLICY_FILE_PATH): if os.path.isfile(UNATTENDED_UPGRADE_POLICY_FILE_PATH):
autoupgradepolicy.reload_config()
if autoupgradepolicy.GetOptionValue('autoUpgradeState') == 'on':
random_time = get_random_time(autoupgradepolicy.GetOptionValue('downloadTime'),DOWNLOAD_RANDOM)
if autoupgradepolicy.GetOptionValue('downloadMode') == 'timing':
background_scheduler.add_job(task,'cron', args=['download'],id='download', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
if autoupgradepolicy.GetOptionValue('installMode') == 'timing':
random_time = random_time + datetime.timedelta(minutes=INTERVAL_DOWN_INSTALL)
background_scheduler.add_job(task,'cron', args=['install'],id='install', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
else:
background_scheduler.pause_job('download')
background_scheduler.pause_job('install')
if autoupgradepolicy.GetOptionValue('preDownload') == 'on':
random_time = get_random_time(autoupgradepolicy.GetOptionValue('preDownloadTime'),PREDOWNLOAD_RANDOM)
background_scheduler.add_job(task,'cron', args=['predownload'],id='download', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
else:
background_scheduler.pause_job('predownload')
joblist = background_scheduler.get_jobs()
for job in joblist:
logging.debug("job:%s,next run time:%s"%(job.id,job.next_run_time))
'''
self.download_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_MODE) self.download_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_MODE)
self.install_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_INSTALL_MODE) self.install_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_INSTALL_MODE)
self.preDownload = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_PREDOWNLOAD) self.preDownload = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_PREDOWNLOAD)
@ -887,37 +1022,35 @@ class UnattendedUpgradesShutdown():
logging.info("upgrade time: [%d:%d] [%d:%d] predown[%s] autoupgrade[%s] d-mode[%s] i-mode[%s]", logging.info("upgrade time: [%d:%d] [%d:%d] predown[%s] autoupgrade[%s] d-mode[%s] i-mode[%s]",
self.download_time_r['h'], self.download_time_r['m'],self.install_time_r['h'],self.install_time_r['m'], self.download_time_r['h'], self.download_time_r['m'],self.install_time_r['h'],self.install_time_r['m'],
self.preDownload, self.autoUpgrade, self.download_mode, self.install_mode) self.preDownload, self.autoUpgrade, self.download_mode, self.install_mode)
'''
else: else:
logging.debug("unattended-upgrades-policy.conf not exist") logging.debug("unattended-upgrades-policy.conf not exist")
'''
def upgrade_all_now_handler(): def upgrade_all_now_handler():
now=datetime.datetime.now()
random_time = now + datetime.timedelta(minutes=DOWNLOAD_RANDOM)
background_scheduler.add_job(task,'date', args=['download_and_install'],id='download', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
joblist = background_scheduler.get_jobs()
for job in joblist:
logging.debug("job:%s,next run time:%s"%(job.id,job.next_run_time))
#self._wait_for_unattended_upgrade_finish() #self._wait_for_unattended_upgrade_finish()
''' logging.info("upgrade all now sinal received")
delta = random.randint(0,int(autoupgradepolicy.GetOptionValue('randomRange')))
run_date = datetime.datetime.now() + datetime.timedelta(minutes=delta)
background_scheduler.add_job(task,'date', run_date = run_date,args=['download_and_install'],\
id='download_and_install', replace_existing=True)
joblist = background_scheduler.get_jobs()
for job in joblist:
logging.debug("job:%s,next run time:%s"%(job.id,job.next_run_time))
'''
if FindRuningUnattendedUpgrades(): if FindRuningUnattendedUpgrades():
logging.warning("find runing unattended-upgrades,please wait") logging.warning("find runing unattended-upgrades,please wait")
return False return False
else: else:
self._pause_timer() #self._pause_timer()
env = copy.copy(os.environ) env = copy.copy(os.environ)
retdownload = subprocess.run(["kylin-unattended-upgrade","--download-only"], env=env) retdownload = subprocess.run(["kylin-unattended-upgrade","--download-only"], env=env)
retinstall = subprocess.run(["kylin-unattended-upgrade","--install-only"], env=env) retinstall = subprocess.run(["kylin-unattended-upgrade","--install-only"], env=env)
self._resume_timer() #self._resume_timer()
if retdownload == 0 and retinstall == 0: if retdownload == 0 and retinstall == 0:
return True return True
else: else:
return False return False
''' '''
def prepare_for_shutdown_handler(active): def prepare_for_shutdown_handler(active):
""" Handle PrepareForShutdown() """ """ Handle PrepareForShutdown() """
if not active: if not active:
@ -946,8 +1079,13 @@ class UnattendedUpgradesShutdown():
self.mainloop.quit() self.mainloop.quit()
self.get_update_proxy() self.get_update_proxy()
self.get_update_interface() self.get_update_interface()
self.update_proxy.connect_to_signal("ChangeUpgradePolicy",change_upgrade_policy_handler) self.get_upgrade_strategy_proxy()
self.update_proxy.connect_to_signal("UpgradeAllNow",upgrade_all_now_handler) self.get_upgrade_strategy_interface()
self.upgrade_strategy_proxy.connect_to_signal("PropertyChanged",property_changed_handler)
self.upgrade_strategy_proxy.connect_to_signal("UpgradeAllNow",upgrade_all_now_handler)
#self.update_proxy.connect_to_signal("ChangeUpgradePolicy",change_upgrade_policy_handler)
#self.update_proxy.connect_to_signal("UpgradeAllNow",upgrade_all_now_handler)
try: try:
self.get_logind_proxy().connect_to_signal( self.get_logind_proxy().connect_to_signal(
@ -967,21 +1105,22 @@ class UnattendedUpgradesShutdown():
logging.debug("Skip waiting for signals, starting operation " logging.debug("Skip waiting for signals, starting operation "
"now") "now")
# self.start_iterations() # self.start_iterations()
'''
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis': if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
logging.info("setting startup download timer") logging.info("setting startup download timer")
GLib.timeout_add(300*1000, lambda: self.timing_download() and False) GLib.timeout_add(300*1000, lambda: self.timing_download() and False)
#local_time =time.localtime(time.time()+300) #local_time =time.localtime(time.time()+300)
self.startup_download_job = self.scheduler.add_job(self.timing_download,'cron',hour=self.download_time_r['h'],minute = self.download_time_r['m']) #self.startup_download_job = self.scheduler.add_job(self.timing_download,'cron',hour=self.download_time_r['h'],minute = self.download_time_r['m'])
else: else:
'''
if self.autoUpgrade == FeatureSwitch.ON.value: if self.autoUpgrade == FeatureSwitch.ON.value:
logging.debug("download time:[%d:%d] install time:[%d:%d]", self.download_time_r['h'], self.download_time_r['m'],self.install_time_r['h'],self.install_time_r['m']) logging.debug("download time:[%d:%d] install time:[%d:%d]", self.download_time_r['h'], self.download_time_r['m'],self.install_time_r['h'],self.install_time_r['m'])
self.download_job = self.scheduler.add_job(self.timing_download, 'cron', hour=self.download_time_r['h'], minute=self.download_time_r['m']) self.download_job = self.scheduler.add_job(self.timing_download, 'cron', hour=self.download_time_r['h'], minute=self.download_time_r['m'])
self.install_job = self.scheduler.add_job(self.timing_install, 'cron', hour=self.install_time_r['h'], minute=self.install_time_r['m']) self.install_job = self.scheduler.add_job(self.timing_install, 'cron', hour=self.install_time_r['h'], minute=self.install_time_r['m'])
elif self.autoUpgrade == FeatureSwitch.OFF.value: elif self.autoUpgrade == FeatureSwitch.OFF.value:
logging.info("auto upgrade turned off") logging.info("auto upgrade turned off")
''' '''
pass
#TimerThread(self.scheduler).start() #TimerThread(self.scheduler).start()
self.mainloop.run() self.mainloop.run()
logging.info("quit mainloop") logging.info("quit mainloop")
@ -1017,9 +1156,11 @@ class UnattendedUpgradesShutdown():
env = copy.copy(os.environ) env = copy.copy(os.environ)
#env["UNATTENDED_UPGRADES_FORCE_INSTALL_ON_SHUTDOWN"] = "1" #env["UNATTENDED_UPGRADES_FORCE_INSTALL_ON_SHUTDOWN"] = "1"
logging.info("starting unattended-upgrades in shutdown mode") logging.info("starting unattended-upgrades in shutdown mode")
'''
if FindRuningUnattendedUpgrades(): if FindRuningUnattendedUpgrades():
logging.warning("another unattended-upgrade is running , quit") logging.warning("another unattended-upgrade is running , quit")
return False return False
'''
self.on_shutdown_mode_uu_proc = subprocess.Popen( self.on_shutdown_mode_uu_proc = subprocess.Popen(
["kylin-unattended-upgrade","--install-only","--mode=shutdown"], env=env) ["kylin-unattended-upgrade","--install-only","--mode=shutdown"], env=env)
#log_msg(_("Running unattended-upgrades in shutdown mode")) #log_msg(_("Running unattended-upgrades in shutdown mode"))
@ -1178,18 +1319,37 @@ if __name__ == "__main__":
if not os.path.exists(logdir): if not os.path.exists(logdir):
os.makedirs(logdir) os.makedirs(logdir)
logfile = os.path.join(logdir, "unattended-upgrades-shutdown.log") logfile = os.path.join(logdir, "unattended-upgrades-shutdown.log")
logging.basicConfig(filename=logfile, #_setup_logging(options,logfile)
level=level, # logging.basicConfig(filename=logfile,
format="%(asctime)s %(levelname)s - %(message)s") # level=level,
logging.getLogger('apscheduler').setLevel(logging.DEBUG) # format="%(asctime)s %(levelname)s - %(message)s")
logging.basicConfig(format='%(asctime)s-%(name)s-%(levelname)s-%(message)s',level=logging.DEBUG,filename=logfile)
# file_handler = logging.FileHandler(filename=logfile)
# file_handler.setLevel(logging.DEBUG)
# formatter = logging.Formatter()
# file_handler.setFormatter(formatter)
# stdout_handler = logging.StreamHandler(sys.stdout)
# stdout_handler.setLevel(logging.DEBUG)
# logger=logging.getLogger()
# logger.setLevel(logging.DEBUG)
# logger.addHandler(file_handler)
# logger.addHandler(stdout_handler)
# scheduler_logger = logging.getLogger('apscheduler')
# scheduler_logger.setLevel(logging.DEBUG)
# scheduler_logger.addHandler(file_handler)
# scheduler_logger.addHandler(stdout_handler)
os_release_info = ReadOsRelease('/etc/os-release') os_release_info = ReadOsRelease('/etc/os-release')
logging.info("project id:%s,sub-project id:%s"%(os_release_info['PROJECT_CODENAME'],os_release_info['SUB_PROJECT_CODENAME'])) logging.info("project id:%s,sub-project id:%s"%(os_release_info['PROJECT_CODENAME'],os_release_info['SUB_PROJECT_CODENAME']))
'''
time_stamp = "0" time_stamp = "0"
if os.path.exists(TIME_STAMP): if os.path.exists(TIME_STAMP):
with open(TIME_STAMP,'r') as f: with open(TIME_STAMP,'r') as f:
time_stamp = f.readline() time_stamp = f.readline()
logging.info("time stamp:%s"%time_stamp) logging.info("time stamp:%s"%time_stamp)
'''
# setup gettext # setup gettext
localesApp = "unattended-upgrades" localesApp = "unattended-upgrades"
localesDir = "/usr/share/locale" localesDir = "/usr/share/locale"
@ -1214,6 +1374,7 @@ if __name__ == "__main__":
signal.signal(signal.SIGTERM, signal_term_handler) signal.signal(signal.SIGTERM, signal_term_handler)
signal.signal(signal.SIGHUP, signal.SIG_IGN) signal.signal(signal.SIGHUP, signal.SIG_IGN)
dpkg_fix=None dpkg_fix=None
'''
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis': if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
dpkg_journal_dirty = is_dpkg_journal_dirty() dpkg_journal_dirty = is_dpkg_journal_dirty()
logging.info("dpkg dirty:%s"%(dpkg_journal_dirty)) logging.info("dpkg dirty:%s"%(dpkg_journal_dirty))
@ -1232,9 +1393,11 @@ if __name__ == "__main__":
logging.info("abnormal pkg count:%s"%(abnormal_pkg_count)) logging.info("abnormal pkg count:%s"%(abnormal_pkg_count))
if abnormal_pkg_count != '0': if abnormal_pkg_count != '0':
apt_fix = subprocess.run("echo y|apt install -f",shell=True,stdout=open(logfile,'a+'),stderr=open(logfile,'a+')) apt_fix = subprocess.run("echo y|apt install -f",shell=True,stdout=open(logfile,'a+'),stderr=open(logfile,'a+'))
'''
kylin_system_updater = KylinSystemUpdater() kylin_system_updater = KylinSystemUpdater()
autoupgradepolicy = AutoUpgradePolicy() autoupgradepolicy = AutoUpgradePolicy()
background_scheduler = BackgroundScheduler(timezone = "Asia/Shanghai") background_scheduler = BackgroundScheduler()
background_scheduler_init(background_scheduler) background_scheduler_init(background_scheduler)
#executor = ThreadPoolExecutor(max_workers=1)
UnattendedUpgradesShutdown(options).run() UnattendedUpgradesShutdown(options).run()
#main() #main()