diff --git a/backend/SystemUpdater/Core/DataAcquisition.py b/backend/SystemUpdater/Core/DataAcquisition.py
index 33b0d20..b8736a0 100644
--- a/backend/SystemUpdater/Core/DataAcquisition.py
+++ b/backend/SystemUpdater/Core/DataAcquisition.py
@@ -16,6 +16,7 @@ import tarfile
import requests
import datetime
import threading
+import subprocess
from email import message
from datetime import datetime
@@ -32,6 +33,7 @@ from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
LOCALTIDDIR = "/var/lib/kylin-system-updater/"
LOCALTIDFILE = "tidfile.conf"
MSGSNDDIR = "/var/lib/kylin-system-updater/sendinfos/"
+SERVERID = "/var/lib/kylin-software-properties/config/serverID.conf"
SOURCE_PKGNAME = {
'Kylin System Updater': 'kylin-system-updater',
@@ -126,6 +128,17 @@ class UpdateMsgCollector():
UploadMessage['UUID'] = str(local_uuid)
else:
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:
logging.error(str(e))
@@ -186,7 +199,6 @@ class UpdateMsgCollector():
try:
self.upgrade_list = upgrade_list
self.upgrade_mode = mode
- self.uuid = str(uuid.uuid1())
self.UpdateInfos.update({"upgradeMode":self.mode_map.get(self.upgrade_mode, "default-mode")})
except DBusException as e:
logging.error(e)
@@ -196,6 +208,11 @@ class UpdateMsgCollector():
tmp_dict = {}
tmp_dict.update(dict_msg)
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, "")})
if self.upgrade_mode == self.MODE_INSTALL_SYSTEM:
self.UpdateInfos.update({"appname":"Upgrade System"})
@@ -222,10 +239,16 @@ class UpdateMsgCollector():
self.background_version.update({pkg.name:"Unknown"})
self.background_list.append(pkg.name)
+ def Init_UUID(self):
+ if self.uuid == "":
+ self.uuid = str(uuid.uuid1())
+
def Msg_Clean(self):
self.UploadMessage = {}
self.PackageInfo = {}
self.UpdateInfos = {}
+ self.uuid = ""
+
class FormatConvert():
def __init__(self, DataCollector):
#秘钥
diff --git a/backend/SystemUpdater/Core/DataMigration.py b/backend/SystemUpdater/Core/DataMigration.py
index e6bb6fa..e7ba57c 100755
--- a/backend/SystemUpdater/Core/DataMigration.py
+++ b/backend/SystemUpdater/Core/DataMigration.py
@@ -315,7 +315,7 @@ def CopyData():
if (_is_first_migration(new_db, 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.commit()
else:
@@ -324,11 +324,11 @@ def CopyData():
# 新增 firstmigration 字段
sql_commnd = "alter table display add column firstmigration text;"
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)
#数据迁移
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.commit()
diff --git a/backend/SystemUpdater/Core/Database.py b/backend/SystemUpdater/Core/Database.py
index 6b8715e..f9c3d7f 100644
--- a/backend/SystemUpdater/Core/Database.py
+++ b/backend/SystemUpdater/Core/Database.py
@@ -9,6 +9,7 @@ import shutil
import sqlite3
import logging
import datetime
+from operator import itemgetter
from gettext import gettext as _
from sys import exec_prefix
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")
# 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"}]
DISPALY_LIST = []
class Sqlite3Server(object):
- def __init__(self, updateManager):
+ def __init__(self, updateManager, _no_DataMigration=False):
self.connect = None
self.window_main = updateManager
self.config_path = get_config_patch()
@@ -33,8 +37,31 @@ class Sqlite3Server(object):
# uncoverable配置文件
self.ucconfigs = UpgradeConfig(datadir = "/etc/kylin-version", name = "kylin-system-version.conf")
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):
try:
logging.info(_("Initialize database files ..."))
@@ -48,7 +75,6 @@ class Sqlite3Server(object):
#connect连接数据库
def connect_database(self):
try:
- logging.debug("Connect database ...")
self.connect = sqlite3.connect(DB_FILE, check_same_thread=False)
self.cursor = self.connect.cursor()
except Exception as e:
@@ -57,10 +83,9 @@ class Sqlite3Server(object):
#disconnect连接数据库
def disconnect_database(self):
try:
- logging.debug("Disconnect database ...")
if self.connect != None:
self.connect.close()
- if self.connect != None:
+ if self.cursor != None:
del self.cursor
except Exception as e:
logging.error("Failed to disconnect database: %s", str(e))
@@ -194,12 +219,49 @@ class Sqlite3Server(object):
logging.info(_("Database: Insert To updateinfos Complete..."))
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 = ''):
errstr = error_string + " " + error_desc
status = " "
status_cn = " "
appname_cn = ""
+ errorcode = "10000"
UpdateInfos = {}
InstallInfos = {}
time = datetime.datetime.now()
@@ -215,9 +277,11 @@ class Sqlite3Server(object):
if success:
status = 'success'
status_cn = '成功'
+ errorcode = "10000000"
else:
status = 'failed'
status_cn = '失败'
+ errorcode = "10000100"
changeLog = ""
try:
@@ -233,17 +297,21 @@ class Sqlite3Server(object):
UpdateInfos.update({"appname":str(pkgname)})
UpdateInfos.update({"source":"Kylin System Updater"})
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())
#安装信息install-infos
InstallInfos.update({"appname":str(pkgname)})
- if pkgname in self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'].keys():
- InstallInfos.update({"old_version":str(self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'][pkgname])})
+ if pkgname in self.window_main.main_meta.versoin_pkgs['groups_upgrade'].keys():
+ InstallInfos.update({"old_version":str(self.window_main.main_meta.versoin_pkgs['groups_upgrade'][pkgname])})
else:
InstallInfos.update({"old_version":'UnKnown'})
InstallInfos.update({"new_version":str(pkgversion)})
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())
# 系统升级完成 ..判断版本号
if status == "success" and "kylin-update-desktop-system" in pkgname:
@@ -256,7 +324,7 @@ class Sqlite3Server(object):
self._removal_of_marker()
#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")
with open(file_path, "r") as stream:
try:
@@ -299,22 +367,26 @@ class Sqlite3Server(object):
UpdateInfos.update({"appname":str(pkgname)})
UpdateInfos.update({"source":"Kylin System Updater"})
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())
#安装信息install-infos
InstallInfos.update({"appname":str(pkgname)})
- if pkgname in self.window_main.update_list.upgrade_meta.versoin_pkgs['single_upgrade'].keys():
- InstallInfos.update({"old_version":str(self.window_main.update_list.upgrade_meta.versoin_pkgs['single_upgrade'][pkgname])})
+ if pkgname in self.window_main.main_meta.versoin_pkgs['single_upgrade'].keys():
+ InstallInfos.update({"old_version":str(self.window_main.main_meta.versoin_pkgs['single_upgrade'][pkgname])})
else:
InstallInfos.update({"old_version":'UnKnown'})
InstallInfos.update({"new_version":str(pkgversion)})
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())
# 软件商店获取中文名
appname_cn = self.get_cn_appname(str(pkgname))
#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:
self.insert_into_updateinfo(pkgname, pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn, status_cn, changeLog)
# FIXME: 发送插入数据库成功的信号local_upgrade_list
@@ -344,17 +416,21 @@ class Sqlite3Server(object):
UpdateInfos.update({"appname":str(pkg.name)})
UpdateInfos.update({"source":"Kylin System Updater"})
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())
#安装信息install-infos
InstallInfos.update({"appname":str(pkg.name)})
- if pkg.name in self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'].keys():
- InstallInfos.update({"old_version":str(self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'][pkg.name])})
+ if pkg.name in self.window_main.main_meta.versoin_pkgs['groups_upgrade'].keys():
+ InstallInfos.update({"old_version":str(self.window_main.main_meta.versoin_pkgs['groups_upgrade'][pkg.name])})
else:
InstallInfos.update({"old_version":'UnKnown'})
InstallInfos.update({"new_version":str(pkgversion)})
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())
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.window_main.dbusController.UpdateSqlitSingle(str(i), timestr)
#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
for i in pkg_group:
# FIXME: 获取组信息
@@ -377,17 +453,21 @@ class Sqlite3Server(object):
UpdateInfos.update({"appname":str(i)})
UpdateInfos.update({"source":"Kylin System Updater"})
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())
#安装信息install-infos
InstallInfos.update({"appname":str(i)})
- if i in self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'].keys():
- InstallInfos.update({"old_version":str(self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'][i])})
+ if i in self.window_main.main_meta.versoin_pkgs['groups_upgrade'].keys():
+ InstallInfos.update({"old_version":str(self.window_main.main_meta.versoin_pkgs['groups_upgrade'][i])})
else:
InstallInfos.update({"old_version":'UnKnown'})
InstallInfos.update({"new_version":str(pkgversion)})
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())
try:
self.window_main.collector.UpdateMsg("InstallInfos", json_file)
@@ -395,7 +475,7 @@ class Sqlite3Server(object):
pass
#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")
with open(file_path, "r") as stream:
try:
@@ -435,6 +515,7 @@ class Sqlite3Server(object):
logging.warning("Cache is None.")
except Exception as e:
logging.error("record update error: %s.",str(e))
+ self.window_main.collector.Msg_Clean()
# 获取group信息
def GetGroupmsg(self, appname):
@@ -508,7 +589,7 @@ class Sqlite3Server(object):
sql = "select init_version from display where id=1"
self.cursor.execute(sql)
_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()
logging.info("Need to refresh version ...")
self._refresh_system_version(update_version, os_version)
@@ -517,7 +598,6 @@ class Sqlite3Server(object):
self.connect.commit()
except Exception as e:
logging.error(str(e))
- self.disconnect_database()
self.disconnect_database()
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]
if "=" in os_version:
os_version = str(os_version).split('=')[-1]
- os_version = os_version.strip()
- update_version = update_version.strip()
#刷新系统版本号:os_version
if update_version == '':
@@ -538,7 +616,7 @@ class Sqlite3Server(object):
for line in lines:
if "KYLIN_RELEASE_ID" in line:
os_version = line.split('=')[1]
- os_version = os_version.strip()
+ os_version = os_version.strip().strip('"')
if not pseudo_version:
if len(os_version) != 0:
self.ucconfigs.setValue("SYSTEM","os_version",str(os_version),True)
@@ -579,7 +657,7 @@ class Sqlite3Server(object):
for line in lines:
if "KYLIN_RELEASE_ID" in line:
os_version = line.split('=')[1]
- os_version = eval(os_version.strip())
+ os_version = os_version.strip().strip('"')
if update_version == "" and os_version != "":
update_version = os_version
elif update_version != "" and os_version == "":
@@ -675,6 +753,268 @@ class Sqlite3Server(object):
except Exception as e:
logging.error(e)
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
def listtojsonstr(lists):
diff --git a/backend/SystemUpdater/Core/JsonConfigParser.py b/backend/SystemUpdater/Core/JsonConfigParser.py
new file mode 100755
index 0000000..082bceb
--- /dev/null
+++ b/backend/SystemUpdater/Core/JsonConfigParser.py
@@ -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
diff --git a/backend/SystemUpdater/Core/LocalUpgradeData.py b/backend/SystemUpdater/Core/LocalUpgradeData.py
new file mode 100644
index 0000000..e6493e2
--- /dev/null
+++ b/backend/SystemUpdater/Core/LocalUpgradeData.py
@@ -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
\ No newline at end of file
diff --git a/backend/SystemUpdater/Core/PluginManager.py b/backend/SystemUpdater/Core/PluginManager.py
new file mode 100644
index 0000000..19eda71
--- /dev/null
+++ b/backend/SystemUpdater/Core/PluginManager.py
@@ -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)
+
diff --git a/backend/SystemUpdater/Core/UpdateList.py b/backend/SystemUpdater/Core/UpdateList.py
index cf5c987..eb0642d 100644
--- a/backend/SystemUpdater/Core/UpdateList.py
+++ b/backend/SystemUpdater/Core/UpdateList.py
@@ -7,42 +7,19 @@ import json
import yaml
import shutil
from gi.repository import Gio
-from .OriginFilter import UpdateListFilterCache
from .errors import *
from .enums import *
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():
- 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'
def __init__(self,parent):
self.parent = parent
#所有的组升级安装列表
- self.upgrade_meta = LocalUpgradeDataList({},[],[],[])
+ self.update_meta = self.parent.main_meta
if 'XDG_CURRENT_DESKTOP' in os.environ:
self.current_desktop = os.environ.get('XDG_CURRENT_DESKTOP')
@@ -56,32 +33,22 @@ class UpdateList():
self.application_dirs = [os.path.join(base, 'applications')
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文件
- def _empty_output_dir(self):
+ def _empty_output_dir(self,path):
#清空 升级列表
- if not os.path.exists(self.OUTPUT_CONFIG_PATH):
- os.makedirs(self.OUTPUT_CONFIG_PATH)
- logging.info('making the ConfigPath(%s) is complete...',self.OUTPUT_CONFIG_PATH)
+ if not os.path.exists(path):
+ os.makedirs(path)
+ logging.info('making the ConfigPath(%s) is complete...',path)
else:
- shutil.rmtree(self.OUTPUT_CONFIG_PATH)
- os.makedirs(self.OUTPUT_CONFIG_PATH)
- logging.info('Emptying the ConfigPath(%s) is complete...',self.OUTPUT_CONFIG_PATH)
+ shutil.rmtree(path)
+ os.makedirs(path)
+ logging.info('Emptying the ConfigPath(%s) is complete...',path)
#读取推送列表,判断分组和单包推送,再进行源过滤
def _make_important_list(self,cache,pkgs_upgrade,important_list = []):
upgradeable_pkgs = []
- tmp = []
+ # tmp = []
upgradeable_groups = []
logging.info("The Server Push List: %a",important_list)
@@ -94,17 +61,12 @@ class UpdateList():
if pkg_obj.is_installed:
if pkg_name in pkgs_upgrade:
pkgs_upgrade.remove(pkg_name)
- tmp.append(pkg_obj)
+ upgradeable_pkgs.append(pkg_obj.name)
else:
- tmp.append(pkg_obj)
+ upgradeable_pkgs.append(pkg_obj.name)
else:
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)
return upgradeable_groups,upgradeable_pkgs
@@ -144,12 +106,12 @@ class UpdateList():
pass
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 = {}
output_json = {}
#FIXME: 确定输出文件的文件名 以及放置位置
- output_config_name = self.OUTPUT_CONFIG_PATH + data['package'] + '.json'
+ output_config_name = output_path + data['package'] + '.json'
#4、添加一些基础信息
groups_base_info.update({"package":data['package']})
@@ -172,57 +134,12 @@ class UpdateList():
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)
-
- #进行源过滤,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):
- pkgs_install,pkgs_upgrade = self._make_pkgs_list(cache,upgrade_data.groups_pkgs,upgrade_data.upgrade_groups,upgrade_data.single_pkgs)
- split_adjust_pkgs = [i.split("=")[0] for i in _adjust_pkgs]
+ def _make_autoupgrade_config(self,cache,output_path,config_path):
+ pkgs_install,pkgs_upgrade = self.update_meta.get_pkgs_total(cache)
- output_config_name = self.OUTPUT_CONFIG_PATH + 'auto-upgrade-list.json'
+ output_config_name = output_path + 'auto-upgrade-list.json'
output_json = {}
install_info = {}
for pkg in pkgs_install:
@@ -230,11 +147,7 @@ class UpdateList():
pkgs_json = {}
pkgs_json.update({"cur_version":getattr(pkg_cache.installed, "version", '')})
- if pkg in split_adjust_pkgs:
- 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({"new_version":getattr(pkg_cache.candidate, "version", '')})
install_info.update({pkg:pkgs_json})
upgrade_json = {}
@@ -243,18 +156,14 @@ class UpdateList():
pkgs_json = {}
pkgs_json.update({"cur_version":getattr(pkg_cache.installed, "version", '')})
- if pkg in split_adjust_pkgs:
- 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({"new_version":getattr(pkg_cache.candidate, "version", '')})
upgrade_json.update({pkg:pkgs_json})
group_json = {}
- for ug in self.upgrade_meta.groups_pkgs:
+ for ug in self.update_meta.get_groups():
pkgs_json = {}
- with open(self.config_path + str(ug) + ".yaml", "r") as stream:
+ with open(config_path + str(ug) + ".yaml", "r") as stream:
try:
data_yaml = yaml.safe_load(stream)
pkgs_json.update({"cur_version":""})
@@ -265,16 +174,12 @@ class UpdateList():
group_json.update({ug:pkgs_json})
single_json = {}
- for us in self.upgrade_meta.single_pkgs:
+ for us in self.update_meta.get_singles():
pkg_cache = cache[us]
pkgs_json = {}
pkgs_json.update({"cur_version":getattr(pkg_cache.installed, "version", '')})
- if pkg in split_adjust_pkgs:
- 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({"new_version":getattr(pkg_cache.candidate, "version", '')})
pkgs_json.update({"changelog":""})
single_json.update({us:pkgs_json})
@@ -356,57 +261,36 @@ class UpdateList():
def _make_groups_pkgs(self,cache,data,pkgs_upgrade = []):
upgrade_pkgs_list = data['upgrade_list']
- #检查包是否在cache中 以及是否已经安装 没有安装的话才添加到列表
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_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:
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:
new_install_list.remove(pkg)
return new_install_list,new_upgrade_list
-
- def _make_groups_upgrade(self,cache,group_list,is_openkylin,pkgs_install,pkgs_upgrade):
+ def _make_groups_upgrade(self,cache,group_list,is_openkylin,pkgs_install,pkgs_upgrade,output_path,config_path):
upgrade_list = []
install_list = []
- if os.path.isdir(self.config_path) == False:
- logging.warning("configPath(%s) is not exists...",self.config_path)
+ if os.path.isdir(config_path) == False:
+ logging.warning("configPath(%s) is not exists...",config_path)
return
- files = os.listdir(self.config_path) #获得文件夹中所有文件的名称列表
+ files = os.listdir(config_path) #获得文件夹中所有文件的名称列表
for ifile in files:
- #判是否是目录以及是否以JSON结尾
if ifile.endswith('.json'):
#读取组JSON文件
- with open(self.config_path+ifile,'r') as f:
+ with open(config_path+ifile,'r') as f:
try:
data = json.load(f)
except Exception as exc:
@@ -415,7 +299,7 @@ class UpdateList():
group_name = data['package']
#读取组的yaml 文件的changelog的信息
- with open(self.config_path + group_name + ".yaml", "r") as stream:
+ with open(config_path + group_name + ".yaml", "r") as stream:
try:
data_yaml = yaml.safe_load(stream)
except Exception as exc:
@@ -425,7 +309,7 @@ class UpdateList():
#过滤没有推送的配置文件
if not group_name in group_list:
continue
-
+
if is_openkylin == True:
install_list,upgrade_list = pkgs_install,pkgs_upgrade
else:
@@ -440,45 +324,53 @@ class UpdateList():
#2、生成安装的软件列表
install_pkgs_json = self._make_pkg_info_json(cache,install_list)
#输出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:''})
- #添加到字典维护的升级列表
- self.upgrade_meta.upgrade_groups.append(group_name)
- self.upgrade_meta.groups_pkgs.update({group_name:{"pkgs_upgrade":upgrade_list,"pkgs_install":install_list}})
+ update_script = data.setdefault("script",{})
+
+ 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))
else:
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):
score = 0
desktop_file = os.path.basename(application.get_filename())
@@ -533,12 +425,12 @@ class UpdateList():
else:
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:
zh_name = ''
base_info = {}
output_json = {}
- output_config_name = self.OUTPUT_CONFIG_PATH + pkg + '.json'
+ output_config_name = output_path + pkg + '.json'
pkg_cache = cache[pkg]
@@ -576,7 +468,7 @@ class UpdateList():
logging.info("Generate Jsonfile(%s) to complete... ",output_config_name)
#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):
pkgs_upgrade = []
@@ -597,37 +489,36 @@ class UpdateList():
return pkgs_install,pkgs_upgrade
def update_kylin(self,cache,important_data,is_openkylin = False):
- pkgs_install = []
- pkgs_upgrade = []
+ system_install = []
+ system_upgrade = []
#查找所有可升级的包
if is_openkylin == True:
- pkgs_install,pkgs_upgrade = self._make_distupgrade(cache)
+ system_install,system_upgrade = self._make_distupgrade(cache)
else:
for pkg in cache:
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_important_list and not self.upgrade_meta.single_pkgs:
- self.parent.dbusController.UpdateDetectFinished(True,[],'','')
+ if not group_list and not single_pkgs:
return
+ self.update_meta.add_singles(single_pkgs)
+
#产生单包的JSON
- self._make_single_upgrade(cache,self.upgrade_meta.single_pkgs)
+ self._make_single_upgrade(cache,single_pkgs,self.OUTPUT_JSON_PATH)
#分组的包的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,'','')
- return
+ self._make_autoupgrade_config(cache,self.OUTPUT_JSON_PATH,get_config_patch())
+ return
\ No newline at end of file
diff --git a/backend/SystemUpdater/Core/UpdaterConfigParser.py b/backend/SystemUpdater/Core/UpdaterConfigParser.py
index bfef7bd..f79ec64 100755
--- a/backend/SystemUpdater/Core/UpdaterConfigParser.py
+++ b/backend/SystemUpdater/Core/UpdaterConfigParser.py
@@ -1,4 +1,5 @@
#!/usr/bin/python3
+# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
# DistUpgradeConfigParser.py
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
@@ -20,20 +21,20 @@ class UpgradeConfig(SafeConfigParser):
self.config_files.append(os.path.join(datadir, defaults_dir))
# our config file
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))
def optionxform(self, optionstr):
return optionstr
- def reReadConfigFiles(self):
- self.read(self.config_files)
+ def reRead(self):
+ self.read(self.config_files, encoding='iso-8859-1')
def setValue(self, section, option, value=None,is_write = True):
if option != 'upgradelist':
logging.info("SetValue Section:%s Option:%s Value:%s",section, option, value)
try:
- self.reReadConfigFiles()
+ self.reRead()
self.set(section, option,value)
except Exception as e:
@@ -48,7 +49,7 @@ class UpgradeConfig(SafeConfigParser):
def getWithDefault(self, section, option, default,re_read=False):
try:
if re_read == True:
- self.reReadConfigFiles()
+ self.reRead()
if type(default) == bool:
return self.getboolean(section, option)
diff --git a/backend/SystemUpdater/Core/enums.py b/backend/SystemUpdater/Core/enums.py
index 5e5aa5f..38da3a1 100644
--- a/backend/SystemUpdater/Core/enums.py
+++ b/backend/SystemUpdater/Core/enums.py
@@ -9,17 +9,25 @@ __all__ = (
"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_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
gettext.bindtextdomain('kylin-system-updater', '/usr/share/locale')
gettext.textdomain('kylin-system-updater')
_ = gettext.gettext
+from aptdaemon.enums import (
+ ERROR_REPO_DOWNLOAD_FAILED
+ )
+
PRIORITY_UPGRADE_SUCCCESSED = "priority-upgrade-successed"
+ERROR_PROGRAM_EXCEPTION = "error_program_exception"
+
#apt update阶段出现的错误解析
ERROR_UPDATE_DEFAULT_FAILED = "error-update-default-failed"
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_SOURCE_FAILED = "error-update-source-failed"
+ERROR_UPDATE_SOURCE_TIMEOUT = "error-update-source-timeout"
ERROR_NETWORK_FAILED = "error-network-failed"
ERROR_NOT_GROUPS_CONFIG = "error-not-groups-config"
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_NOT_UPGRADE_PACKAGES = "error-not-upgrade-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_READ_LOCAL_DEB = "error-read-local-deb"
ERROR_LOCAL_DEB_FORMAT = "error-local-deb-format"
@@ -55,6 +65,7 @@ _STRINGS_ERROR = {
#update
ERROR_UPDATE_DEFAULT_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_UPDATE_KEY_SIGNATURES: _("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_FIX_SYSTEM: _("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."),
@@ -72,14 +84,17 @@ _STRINGS_ERROR = {
ERROR_RESOLVER_FAILED: _("Could not calculate the upgrade"),
ERROR_NOT_UPGRADE_PACKAGES: _("There is an exception in the update package."),
ERROR_REMOVE_ESSENTIAL_PACKAGES: _("There is an exception in the update package."),
+ ERROR_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_READ_LOCAL_DEB:_(" "),
ERROR_LOCAL_DEB_FORMAT:_(" "),
ERROR_INSTALL_DEB_BASE:_(" ")}
_DESCS_ERROR = {
+ ERROR_PROGRAM_EXCEPTION: _("Program exception, please contact the administrator to solve."),
#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_UPDATE_KEY_SIGNATURES: _("Check your source public key signature"),
ERROR_UPDATE_NOTREAD_SOURCES: _("Please check your source list and retry."),
@@ -102,12 +117,45 @@ _DESCS_ERROR = {
ERROR_RESOLVER_FAILED: _("nothing"),
ERROR_NOT_UPGRADE_PACKAGES: _("This update cannot detect the upgradeable package."),
ERROR_REMOVE_ESSENTIAL_PACKAGES: _("You request the removal of a system-essential package."),
+ ERROR_RUN_SCRIPTS_FAILED:_("Exceptions to running the check script."),
ERROR_NOT_DISK_SPACE: _("test"),
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_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
MONIT_DETECT = "step-updatedetect"
MONIT_DEPRESOLUT = "step-depresolution"
@@ -130,6 +178,13 @@ CALLER = {
'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):
"""Get a long description of an error.
@@ -141,6 +196,16 @@ def get_error_description_from_enum(enum):
except KeyError:
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):
"""Get a short description of an error.
@@ -166,4 +231,10 @@ def get_caller_from_enum(enum):
except KeyError:
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
diff --git a/backend/SystemUpdater/Core/utils.py b/backend/SystemUpdater/Core/utils.py
index 2717de1..6069635 100644
--- a/backend/SystemUpdater/Core/utils.py
+++ b/backend/SystemUpdater/Core/utils.py
@@ -57,6 +57,7 @@ import psutil
import ctypes
from ctypes import *
import struct
+from SystemUpdater.Core.enums import get_policykit_authority_action_enum
# 禁止关机锁文件路径
VERIFY_SO = "libkylin_signtool.so"
@@ -731,18 +732,6 @@ def deb_verify(deb_path, _isinstall = False):
_deb_path = str(deb_path)
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"):
logging.error("SOF_InitializeEx error!")
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)
if "Signature Verified failed" in str(ret.stdout).strip() or "签名验证失败" in str(ret.stdout).strip():
logging.info("Signature Verified failed!")
- return 2
elif "Signature Verified Ok" in str(ret.stdout).strip() or "签名验证成功" in str(ret.stdout).strip():
logging.info("Signature Verified Ok!")
return 0
+ else:
+ logging.error("Signature Verified failed:%s.",ret)
+ return 2
except Exception as e:
logging.error(e)
return 3
-def PolicyKit_Authority(details = '', sender = None):
+def PolicyKit_Authority(details = '', sender = None, InstPolicy = False, source=''):
_allow_kylinsign = False
_verify_kylinsign = False
try:
- #获取未知来源应用安装策略Unknown sources apply installation policies
- inst_policies_path = "/etc/dpkg/dpkg.cfg"
- if os.path.isfile(inst_policies_path):
- with open(inst_policies_path, "r") as f:
- lines = f.readlines()
- for line in lines:
- if "allow-kylinsign" in line:
- _allow_kylinsign = True
- if "verify-kylinsign" in line:
- _verify_kylinsign = True
- if _allow_kylinsign == True and _verify_kylinsign == False: #策略: 阻止
- logging.debug("unknown sources apply installation policies: deter")
- return False,_("The package is unsigned, refuses to install.")
- elif _allow_kylinsign == True and _verify_kylinsign == True: #策略: 警告
- logging.debug("unknown sources apply installation policies: warning")
- elif _allow_kylinsign == False and _verify_kylinsign == False: #策略: 关闭
- logging.debug("unknown sources apply installation policies: close")
- else:
- logging.warning("Unknown sources apply installation policies get failed.")
-
+ if InstPolicy:
+ #获取未知来源应用安装策略Unknown sources apply installation policies
+ inst_policies_path = "/etc/dpkg/dpkg.cfg"
+ if os.path.isfile(inst_policies_path):
+ with open(inst_policies_path, "r") as f:
+ lines = f.readlines()
+ for line in lines:
+ if "allow-kylinsign" in line:
+ _allow_kylinsign = True
+ if "verify-kylinsign" in line:
+ _verify_kylinsign = True
+ if _allow_kylinsign == True and _verify_kylinsign == False: #策略: 阻止
+ logging.debug("unknown sources apply installation policies: deter")
+ return False,_("The package is unsigned, refuses to install.")
+ elif _allow_kylinsign == True and _verify_kylinsign == True: #策略: 警告
+ logging.debug("unknown sources apply installation policies: warning")
+ elif _allow_kylinsign == False and _verify_kylinsign == False: #策略: 关闭
+ logging.debug("unknown sources apply installation policies: close")
+ else:
+ logging.warning("Unknown sources apply installation policies get failed.")
+
#用户鉴权
+ logging.debug("Authentication via PolicyKit .")
details = {'polkit.message':details}
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.Interface(kit, 'org.freedesktop.PolicyKit1.Authority')
(granted, notused , details) = kit.CheckAuthorization(
@@ -800,7 +793,7 @@ def PolicyKit_Authority(details = '', sender = None):
except Exception as e:
logging.error(e)
return False,str(e)
-
+
if __name__ == "__main__":
#print(mirror_from_sources_list())
#print(on_battery())
diff --git a/backend/SystemUpdater/UpdateManager.py b/backend/SystemUpdater/UpdateManager.py
index 35987db..30e9bc2 100644
--- a/backend/SystemUpdater/UpdateManager.py
+++ b/backend/SystemUpdater/UpdateManager.py
@@ -22,12 +22,15 @@ from .Core.enums import *
from .Core.MyCache import MyCache
from .UpdateManagerDbus import UpdateManagerDbusController,UpdateManagerDbusControllerUtils,UPDATER_DBUS_INTERFACE,UPDATER_DBUS_PATH,UPDATER_DBUS_SERVICE
from .Core.UpdateList import UpdateList
+from .Core.PluginManager import *
from .backend import InstallBackend,get_backend
from .Core.Database import Sqlite3Server
from .Core.loop import mainloop
from .Core.DataAcquisition import UpdateMsgCollector
+from SystemUpdater.Core.LocalUpgradeData import LocalUpgradeDataList
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.DpkgInstallProgress import LogInstallProgress
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.sqlite3_server = Sqlite3Server(self)
+ self.pm_class = pluginManagerClass()
self.simulate_mode = SimulateTerminal()
self.install_mode = UpdateInstallMode(self)
self.apt_p2p_config = AptP2pConfigManager()
- self._reload_options_config()
+ self.main_meta = LocalUpgradeDataList()
+ json_config()
self._refresh_cache_only()
except Exception as e:
logging.error(e)
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):
"""Start the daemon and listen for calls."""
logging.info("Waiting for calls...")
@@ -131,30 +100,39 @@ class UpdateManager():
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:
if self.install_mode.shutdown_mode() == True and upgrade_mode != InstallBackend.MODE_INSTALL_SINGLE:
+
#部分升级的方式 计算的时候 补上上次更新的内容一起计算
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:
- 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.start(upgrade_content)
+ install_backend.start(push_content)
else:
resolver_backend = get_backend(self, InstallBackend.ACTION_CHECK_RESOLVER,upgrade_mode)
- resolver_backend.start(upgrade_content)
+ resolver_backend.start_resolver(push_content)
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 whether_to_quit_uu():
- 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_INSTALL,upgrade_mode)
- install_backend.start(upgrade_content)
+ install_backend.start(push_content)
else:
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:
logging.error(e)
@@ -162,12 +140,8 @@ class UpdateManager():
def start_update(self,update_mode = InstallBackend.MODE_UPDATE_ALL):
try:
#更新前的准备
- self.configs_cover.reReadConfigFiles()
- self.retry_limit = self.RETRY_LIMIT_NUM
+ # self.install_mode.reset_shutdown_mode()
- self.install_mode.reset_shutdown_mode()
-
- #检查 光盘源
self.install_mode.check_source()
if self.install_mode.check_network() == True:
@@ -185,12 +159,16 @@ class UpdateManager():
self.start_update_backend(update_mode = update_mode)
except UpdateBaseError as excep:
+ self.dbusController.InstallDetectStatus(False,get_error_code_from_enum(excep.code))
self.dbusController.UpdateDetectFinished(False,[''],excep.header,excep.desc)
except UpdateProgressExit:
pass
except Exception as e:
logging.error(e)
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):
#调用aptdeamon进行update
@@ -199,39 +177,47 @@ class UpdateManager():
def start_available(self):
try:
+ self.configs_cover.reRead()
+
+ self.retry_limit = self.RETRY_LIMIT_NUM
+
+ json_config().read()
+
self.refresh_cache()
+ self.main_meta.refresh()
+
self.update_list = UpdateList(self)
- #1、 检查出现安装过程异常重启 出现的话 进行异常修复
if self.configs_uncover.getWithDefault("SystemStatus", "abnormal_reboot", False) == True:
self.configs_uncover.setValue("SystemStatus","abnormal_reboot",str(False),True)
logging.warning("start fix Abnormal Reboot broken pkgs...")
self.start_fix_broken()
return
- #检查当前系统的状态 是否存在系统为破损状态 导致出现异常
self._check_system_broken(self.cache)
+
+ self._check_config_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())
- if self.cache != None and self.cache.get_changes():
- self.cache.clear()
+ self.dbusController.UpdateDetectFinished(True,self.main_meta.get_push(),'','')
except UpdateBaseError as excep:
+ self.dbusController.InstallDetectStatus(False,get_error_code_from_enum(excep.code))
self.dbusController.UpdateDetectFinished(False,[''],excep.header,excep.desc)
except UpdateProgressExit as excep:
pass
except Exception as e:
logging.error(e)
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):
try:
- #第一次进入 之后update不进入
if self.cache is None:
self.cache = MyCache(None)
else:
@@ -245,45 +231,18 @@ class UpdateManager():
raise UpdateBaseError(ERROR_NOT_INIT_PACKAGESINFIO)
def _refresh_cache_only(self):
- #第一次进入 之后update不进入
+ self._reload_options_config()
+
if self.cache is None:
self.cache = MyCache(None)
else:
self.cache.open(None)
self.cache._initDepCache()
- def _check_self_upgrade(self,cache):
+ def _check_config_upgrade(self,cache):
need_upgrade = False
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包
for pkg_name in [self.GROUPS_PKG_NAME]:
if pkg_name in cache:
@@ -318,16 +277,54 @@ class UpdateManager():
if need_upgrade == True:
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()
def _check_system_broken(self,cache):
if cache.get_changes():
cache.clear()
- #获取出现破损状态包的数量
if cache._depcache.broken_count or cache._depcache.del_count > 0 or \
cache._depcache.inst_count > 0:
- #线程获取详细的卸载软件包情况
self.simulate_mode.start_caculate(["apt-get", "install","-f","--simulate"],thread=True)
else:
logging.info("Check: System Apt Cache for Broken Successfully...")
@@ -423,7 +420,14 @@ class UpdateManager():
def start_back_upgrade(self, pkglist):
try:
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:
logging.error(str(e))
@@ -434,6 +438,10 @@ class UpdateManager():
header = ''
desc = ''
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 = {}
UpdateMsg = {}
try:
@@ -445,10 +453,9 @@ class UpdateManager():
sender_name = get_proc_from_dbus_name(sender)
caller = get_caller_from_enum(sender_name)
caller_trans = get_source_name_from_enum(sender_name)
- if source == "kylin-software-center":
- logging.info("caller : %s.",source)
- else:
- (status,error_string) = PolicyKit_Authority(caller_trans+_(" requires authentication to install software packages."),sender)
+ if deb_verify(deb_path) != 0: #验签失败,提权
+ (status,error_string) = PolicyKit_Authority(caller_trans+_(" requires authentication to install software packages."),
+ sender,InstPolicy=True,source=source)
if not status:
self.dbusController.InstalldebFinished(False,error_string,'')
return
@@ -458,6 +465,8 @@ class UpdateManager():
UpdateMsg.update({"source":str(self.deb_obj.get("source","kylin-system-updater"))})
deb_cache, ins, _isinstall = self._suit_install_mode(deb_path)
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)})
if self._is_broken > 0 or not self.cacheSatisfy or self._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)
if dep_satisfy:
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:
self.dbusController.InstalldebFinished(False, header, desc)
except UpdateBaseError as excep:
@@ -508,12 +518,14 @@ class UpdateManager():
_success,header,desc = self._dpkg_purge_pkgs(pkgs_list)
if _success == True:
logging.info(header)
+ # self.dbusController.PurgePackagesFinished(_success,'',desc," ".join(pkgs_list))
self.dbusController.PurgePackagesFinished(_success,'',desc)
else:
+ # self.dbusController.PurgePackagesFinished(_success,header,desc," ".join(pkgs_list))
self.dbusController.PurgePackagesFinished(_success,header,desc)
else:
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()
except Exception as e:
@@ -530,6 +542,26 @@ class UpdateManager():
success = p.returncode == 0
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):
depends_list = []
@@ -637,11 +669,9 @@ class UpdateManager():
satisfy_list.append(debfile)
for depends in noSatisfyList:
for debfile in depends_list:
- if "_" not in debfile and len(debfile.split['_'])!=3:
- break
if "%3a" in debfile:
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
satisfy_list.append(debfile)
if depends_count < len(noSatisfyList) or depends_count < len(depends_pkg):
@@ -687,7 +717,7 @@ class UpdateManager():
def _suit_install_mode(self, deb_path):
self._is_broken = False
self.cacheSatisfy = False
- _is_install = False
+ _is_install=False
absolute_path, debname = os.path.split(deb_path)
# 检查本地破损
try:
@@ -737,11 +767,11 @@ class UpdateManager():
else:
self.cacheSatisfy = False
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):
_noSatisfyList = []
- _group_satify = False
+ _group_satify=False
providers = []
for or_group in depends:
for deb_info in or_group:
@@ -950,7 +980,6 @@ class UpdateInstallMode():
def is_openkylin_desktop(self):
return self.dist == self.OPENKYLIN_DISTTRIBUTOR
- # return True
def check_network(self):
if self.parent.options.no_check_network is False and self.is_disc == False:
@@ -971,14 +1000,12 @@ class UpdateInstallMode():
data = f.read()
important_list = data.split()
else:
- important_list = [self.SYSTEM_UPDATE_GROUPS,self.parent.BACKEND_PKG_NAME,self.parent.APTD_PKG_NAME,self.parent.FRONTEND_PKG_NAME]
- return important_list
+ important_list = [self.SYSTEM_UPDATE_GROUPS]
+
+ #去除重复内容
+ important_list = list(set(important_list))
- def check_filter(self):
- if self.parent.options.close_filter == False and self.is_disc == False and self.is_openkylin_desktop() == False:
- return True
- else:
- return False
+ return important_list
def _plymouth_splash(self):
if os.path.exists("/bin/plymouth"):
@@ -987,6 +1014,17 @@ class UpdateInstallMode():
subprocess.Popen(["/bin/plymouth", "show-splash","--wait"])
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):
"""
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
connection = Gio.bus_get_sync(Gio.BusType.SYSTEM)
- #首先设置systemd默认延长时间为1800
- getter_interface = dbus.Interface(
- self.logind_proxy,
- dbus_interface='org.freedesktop.login1.Manager')
- ret = getter_interface.SetInhibitDelayMaxSec(1800)
+ self._set_inhibit_delay(1800)
var, fdlist = connection.call_with_unix_fd_list_sync(
'org.freedesktop.login1', '/org/freedesktop/login1',
@@ -1011,11 +1045,10 @@ class UpdateInstallMode():
'delay')),
None, 0, -1, None, None)
inhibitor = Gio.UnixInputStream(fd=fdlist.steal_fds()[var[0]])
-
return inhibitor
except Exception as e:
logging.error(e)
- return False
+ return None
def _prompt_in_boot(self):
#关机安装完成之后开机时进行提醒
diff --git a/backend/SystemUpdater/UpdateManagerDbus.py b/backend/SystemUpdater/UpdateManagerDbus.py
index beba797..d1d63be 100755
--- a/backend/SystemUpdater/UpdateManagerDbus.py
+++ b/backend/SystemUpdater/UpdateManagerDbus.py
@@ -75,6 +75,7 @@ class UpdateManagerDbusController(dbus.service.Object):
def _update_important_reply(self,retval):
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),\
enums.get_error_description_from_enum(enums.ERROR_UPDATE_SOURCE_FAILED))
else:
@@ -82,8 +83,9 @@ class UpdateManagerDbusController(dbus.service.Object):
def _update_important_error(self,retval):
logging.error(str(retval))
- 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))
+ self.InstallDetectStatus(False,enums.get_error_code_from_enum(enums.ERROR_UPDATE_SOURCE_TIMEOUT))
+ 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的本次升级的列表
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')
interface = dbus.Interface(obj, dbus_interface='org.debian.apt')
logging.info("Now start to restart Aptdeamon...")
- interface.Quit()
+ interface.Quit(timeout=0.5)
except Exception as e:
logging.error(str(e))
@@ -131,14 +133,30 @@ class UpdateManagerDbusController(dbus.service.Object):
try:
self.UpdateDetectStatusChanged(5,_("Checking network connection"))
obj = self.bus.get_object("org.freedesktop.NetworkManager","/org/freedesktop/NetworkManager")
- interface = dbus.Interface(obj, "org.freedesktop.NetworkManager")
- retval = interface.CheckConnectivity(timeout=0.5)
+ interface = dbus.Interface(obj, "org.freedesktop.DBus.Properties")
+ retval = interface.Get("org.freedesktop.NetworkManager","Connectivity",timeout=0.5)
except Exception:
retval = 4
#1 表示没有网卡可以使用
if retval == 1:
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):
prohibit_list = ["dbus-send","gdbus"]
if sender_name in prohibit_list:
@@ -191,15 +209,15 @@ class UpdateManagerDbusController(dbus.service.Object):
try:
if self.parent.configs_cover.has_section(str(section)) and self.parent.configs_cover.has_option(str(section),str(option)):
value = str(self.parent.configs_cover.get(str(section), str(option)))
- logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+" GetConfigValue section:%s option:%s value:%s ...",section,option,value)
+ # logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+" GetConfigValue section:%s option:%s value:%s ...",section,option,value)
return True,value
if self.parent.configs_uncover.has_section(str(section)) and self.parent.configs_uncover.has_option(str(section),str(option)):
value = str(self.parent.configs_uncover.get(str(section), str(option)))
- logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+" GetConfigValue section:%s option:%s value:%s ...",section,option,value)
+ # logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+" GetConfigValue section:%s option:%s value:%s ...",section,option,value)
return True,value
elif self.parent.sqlite3_server.ucconfigs.has_section(str(section)) and self.parent.sqlite3_server.ucconfigs.has_option(str(section),str(option)):
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
else:
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]
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)
- 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 new_upgrade_list:
+
+ if 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
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
except Exception as e:
logging.info(str(e))
@@ -407,25 +420,28 @@ class UpdateManagerDbusController(dbus.service.Object):
purge_list = [str(pkg) for pkg in _purge_list]
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)
- (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:
self.PurgePackagesFinished(False,details,'')
return self.RETURN_UNKNOWN_CODE,details
#目前只有360使用这个环境变量 当其他包也使用时 可以将这个权限放开
- if "360epp" in purge_list:
+ if True:
#需要对aptdeamon加这两个环境变量 才可以提示弹窗
self.set_aptdeamon_environ("XAUTHORITY","/home/"+str(cur_user)+"/.Xauthority")
self.set_aptdeamon_environ("DISPLAY",":0")
# 处于更新和升级中的话 不进行升级
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."),'')
logging.warning('PurgePackages In the process of updating or Upgrading...')
return self.RETURN_BUSY_STATE,self.RETURN_BUSY_DESC
else:
self._check_prohibit_user(sender_name)
+ self.parent.sqlite3_server.current_purge_pkgs = purge_list
self.parent.start_purge_pkgs(purge_list)
return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
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 ",\
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')
def UpdateDownloadFinished(self, success, upgrade_group,error_string='',error_desc=''):
diff --git a/backend/SystemUpdater/UpgradeStrategies.py b/backend/SystemUpdater/UpgradeStrategies.py
index 78902f9..18ae58b 100644
--- a/backend/SystemUpdater/UpgradeStrategies.py
+++ b/backend/SystemUpdater/UpgradeStrategies.py
@@ -28,7 +28,7 @@ class UpgradeStrategies():
self.dbusController = self._setup_dbus()
#config
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
GLib.timeout_add_seconds(STRATEGY_IDLE_INTERVAL,
diff --git a/backend/SystemUpdater/UpgradeStrategiesDbus.py b/backend/SystemUpdater/UpgradeStrategiesDbus.py
index dec8a97..cc89358 100644
--- a/backend/SystemUpdater/UpgradeStrategiesDbus.py
+++ b/backend/SystemUpdater/UpgradeStrategiesDbus.py
@@ -148,9 +148,9 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
logging.info("Apt-p2p service has been disabled and not need to redisabled...")
return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
else:
- logging.waring("error: input value _status=%s",status)
+ logging.warning("error: input value _status=%s",status)
else:
- logging.waring("apt-p2p function is not install...")
+ logging.warning("apt-p2p function is not install...")
## dbus接口: 开启或关闭预下载功能
@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 True,"success"
- # 设置自动更新时间
- @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='bs',sender_keyword='sender')
- def SetAutoUpgradePeriod(self, period, sender = None):
- 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))
- try:
- self.parent.sqlite3_server.insert_into_display("update_period", period.lower())
- except Exception as e:
- logging.error(str(e))
- return True,"success"
+ # # 设置自动更新时间
+ # @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='bs',sender_keyword='sender')
+ # def SetAutoUpgradePeriod(self, period, sender = None):
+ # 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))
+ # try:
+ # self.parent.sqlite3_server.insert_into_display("update_period", period.lower())
+ # except Exception as e:
+ # logging.error(str(e))
+ # return True,"success"
# 获取数据库值
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='bss', out_signature='s')
diff --git a/backend/SystemUpdater/backend/InstallBackendAptdaemon.py b/backend/SystemUpdater/backend/InstallBackendAptdaemon.py
index 9fbe894..a20bd7c 100644
--- a/backend/SystemUpdater/backend/InstallBackendAptdaemon.py
+++ b/backend/SystemUpdater/backend/InstallBackendAptdaemon.py
@@ -45,11 +45,16 @@ class InstallBackendAptdaemon(InstallBackend):
#客户端连接aptdeamon的dbus接口
self.client = client.AptClient()
self.trans_failed_msg = None
+
+ self.steps_progress_begin = 0
+ self.steps_progress_end = 0
+
+ self.need_retry = False
#是否在安装状态 判断依据进度>50
- self.on_install_stage = False
+ self.on_installing = False
if self.action == self.ACTION_INSTALL_SHUTDOWN:
- self.on_install_stage = True
+ self.on_installing = True
if self.action == self.ACTION_UPDATE:
#更新的超时检查机制 超时时取消下载
@@ -74,7 +79,7 @@ class InstallBackendAptdaemon(InstallBackend):
if self.aptd_base.progress >= 90 or self.simulation_progress > 80:
return False
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
def _check_install_inactivity(self):
@@ -83,6 +88,11 @@ class InstallBackendAptdaemon(InstallBackend):
"""
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:
logging.info("Installing to exit and timeout check quit...")
return False
@@ -93,7 +103,7 @@ class InstallBackendAptdaemon(InstallBackend):
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)
if self.action == self.ACTION_INSTALL_SHUTDOWN:
#关机安装模式 解除禁止关机锁
@@ -108,7 +118,7 @@ class InstallBackendAptdaemon(InstallBackend):
error_string=_("Could not install the upgrades"),
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
else:
self.install_timestamp = self.install_timestamp - 1
@@ -133,7 +143,7 @@ class InstallBackendAptdaemon(InstallBackend):
and self.aptd_base.cancelable == True:
logging.error("Quitting due to inactivity")
- self.window_main.dbusController.transaction.cancel()
+ self.dbus_send.transaction.cancel()
return False
return True
@@ -143,7 +153,7 @@ class InstallBackendAptdaemon(InstallBackend):
"""刷新包cache"""
try:
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,
_("Checking for updates…"), False)
@@ -165,7 +175,7 @@ class InstallBackendAptdaemon(InstallBackend):
trans = yield self.client.commit_packages(
pkgs_install, reinstall, pkgs_remove, purge = purge, upgrade = pkgs_upgrade,
downgrade = pkgs_downgrade,defer=True)
- self.window_main.dbusController.transaction = trans
+ self.dbus_send.transaction = trans
yield self._show_transaction(trans, self.action,
_("Installing updates…"), True)
@@ -195,7 +205,7 @@ class InstallBackendAptdaemon(InstallBackend):
trans = yield self.client.commit_only(
pkgs_install, reinstall, pkgs_remove, purge = purge, upgrade = pkgs_upgrade,
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,
_("Installing updates…"), True)
@@ -217,6 +227,43 @@ class InstallBackendAptdaemon(InstallBackend):
error_string='', error_desc='')
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
def install_deb(self,install_path,install_force):
"""安装deb包 """
@@ -232,7 +279,7 @@ class InstallBackendAptdaemon(InstallBackend):
except Exception as e:
self._action_done(self.ACTION_INSTALL_DEB,
is_cancelled=False, success=False,
- error_string=str(e), error_desc='')
+ error_string=str(e), error_desc='', error_code=e.code)
# raise
@inline_callbacks
@@ -240,7 +287,7 @@ class InstallBackendAptdaemon(InstallBackend):
"""安装deb包 """
try:
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,
_("Installing deb packages…"), False)
@@ -259,7 +306,7 @@ class InstallBackendAptdaemon(InstallBackend):
"""修复未完成的安装 """
try:
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,
_("fix incomplete install"), False)
@@ -278,7 +325,7 @@ class InstallBackendAptdaemon(InstallBackend):
"""清空所有下载的文件 """
try:
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,
_("Remove all downloaded files."), False)
@@ -298,7 +345,7 @@ class InstallBackendAptdaemon(InstallBackend):
try:
# trans = yield self.client.remove_packages(package_names = 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,
_("Installing deb packages…"), False)
@@ -308,25 +355,25 @@ class InstallBackendAptdaemon(InstallBackend):
error_string='', error_desc='')
except Exception as e:
logging.error(str(e))
- # self._action_done(self.ACTION_REMOVE_PACKAGES,
- # is_cancelled=False, success=False,
- # error_string=str(e), error_desc='')
#进度回调
def _on_progress_changed(self, trans,progress,action):
#不要101这种未知状态
if progress == 101:
return
-
- #过滤掉不是线性的进度
- if progress > self.aptd_base.progress:
- self.aptd_base.progress = progress
- else:
- return
- 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)
+ if self.action_mode == self.MODE_INSTALL_STEP:
+ progress = int(self.steps_progress_begin + (progress / 100) *
+ (self.steps_progress_end - self.steps_progress_begin))
+ else:
+ #过滤掉不是线性的进度
+ if progress > self.aptd_base.progress:
+ self.aptd_base.progress = progress
+ else:
+ return
+ self.aptd_base.progress = progress
+ 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):
@@ -338,66 +385,63 @@ class InstallBackendAptdaemon(InstallBackend):
if self.aptd_base.status == None:
return
- 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 _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 progress == 11:
progress = 15
if progress != 100:
- self.window_main.dbusController.UpdateDetectStatusChanged(progress,status)
+ self.dbus_send.UpdateDetectStatusChanged(progress,status)
elif action == self.ACTION_INSTALL:
- #50%时候 属于下载状态切换到安装状态的过程 下面的代码只执行一次
- 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:
+ if self.meta_upgrade.version_upgrade == True and progress >= 48 and 'Failed to fetch' in self.aptd_base.error_details:
logging.warning("Arise Failed to fetch and Need retry Upgrade...")
- self.now_upgrade.need_retry = True
+ self.need_retry = True
return
+ #50%时候 属于下载状态切换到安装状态的过程 下面的代码只执行一次
+ #在安装的阶段的时候就进入安装阶段 禁止关机操作
+ #提前进度安装状态
+ if progress >= 49 and progress < 90 and self.on_installing == False:
+ self.on_installing = True
+ self.entering_installed()
+
#在下载阶段发送取消信号
- if self.on_install_stage == False:
- self.window_main.dbusController.Cancelable(self.aptd_base.cancelable)
-
- self.window_main.dbusController.UpdateDloadAndInstStaChanged(upgrade_content,progress,status,details)
- elif action == self.ACTION_INSTALL_SHUTDOWN:
- # 写入进度 到plymouth
- self._progress_to_plymouth(progress)
- self.window_main.dbusController.UpdateDloadAndInstStaChanged(upgrade_content,progress,status,details)
+ if self.on_installing == False:
+ self.dbus_send.Cancelable(self.aptd_base.cancelable)
+
+ self.dbus_send.UpdateDloadAndInstStaChanged(self.meta_upgrade.get_content(),progress,status,details)
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...")
- self.now_upgrade.need_retry = True
+ self.need_retry = True
return
- self.window_main.dbusController.Cancelable(self.aptd_base.cancelable)
- self.window_main.dbusController.UpdateDloadAndInstStaChanged(upgrade_content,progress,status,details)
+ self.dbus_send.Cancelable(self.aptd_base.cancelable)
+ 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:
- self.window_main.dbusController.FixBrokenStatusChanged(False,True,progress,status,'','')
+ self.dbus_send.FixBrokenStatusChanged(False,True,progress,status,'','')
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:
- self.window_main.dbusController.InstalldebStatusChanged(progress,status,details)
+ self.dbus_send.InstalldebStatusChanged(progress,status,details)
else:
logging.info("Other Action:progress = %d , status = %s ,details = %s",progress,status,details)
def _on_details_changed(self, trans, details,action):
self.aptd_base.details = details
- self._dist_status_changed(action,self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs,\
- self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details)
+ self._dist_status_changed(action,self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details)
def _on_download_changed(self, trans, details):
logging.info(details)
@@ -405,8 +449,7 @@ class InstallBackendAptdaemon(InstallBackend):
# eta 剩余时间不正确,取消掉
def _on_progress_download_changed(self,trans,current_items, total_items, currenty_bytes, total_bytes, current_cps, eta):
if self.action == self.ACTION_INSTALL or self.action == self.ACTION_DOWNLOADONLY or self.action == self.ACTION_BACKGROUND_UPGRADE:
- self.window_main.dbusController.UpdateDownloadInfo(\
- self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs,\
+ self.dbus_send.UpdateDownloadInfo(self.meta_upgrade.get_content(),\
current_items, total_items, \
currenty_bytes, total_bytes, \
current_cps)
@@ -425,27 +468,25 @@ class InstallBackendAptdaemon(InstallBackend):
if self.action != self.ACTION_UPDATE:
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
def _on_config_file_conflict(self, transaction, old, new):
logging.info("Config file conflict oldconf = %s , newconf = %s...",str(old),str(new))
logging.info("Default To Replace Old Configfile...")
- #默认替换旧的配置文件
+
transaction.resolve_config_file_conflict(old, "keep")
- # transaction.resolve_config_file_conflict(old, "keep")
#增加记录当产生错误的时候 详细信息
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)
logging.error(str(error_details))
@inline_callbacks
- def _show_transaction(self, trans, action, header, show_details):
- #更新和升级最后完成和失败都会走此在此进行完成之后的处理
- trans.connect("finished", self._on_finished, action)
+ def _show_transaction_steps(self, trans, action, header, show_details):
+
+ trans.connect("finished", self._on_finished_steps, action)
#升级和更新的状态信息和进度
trans.connect("status-changed", self._on_status_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)
- # yield trans.set_debconf_frontend("ukui")
- # yield trans.set_locale(os.environ["LANGUAGE"] + ".UTF-8")
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):
try:
error_string = ''
error_desc = ''
- #退出
- self.on_install_stage = False
+ error_code = ''
+
if status == EXIT_FAILED:
# self.log_audit(str(trans.error.code))
+ 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 self.trans_failed_msg:
@@ -479,14 +549,36 @@ class InstallBackendAptdaemon(InstallBackend):
error_string = _("Failed to fetch")
error_desc = _("_Cancel Upgrade")
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:
error_string = _("Uninstallation completed")
is_success = (status == EXIT_SUCCESS)
+
self._action_done(action,
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:
logging.error(e)
traceback.print_exc()
diff --git a/backend/SystemUpdater/backend/__init__.py b/backend/SystemUpdater/backend/__init__.py
index 763f4f6..cb55007 100644
--- a/backend/SystemUpdater/backend/__init__.py
+++ b/backend/SystemUpdater/backend/__init__.py
@@ -19,62 +19,26 @@ from gettext import gettext as _
from SystemUpdater.Core.errors import *
from SystemUpdater.Core.enums import *
from SystemUpdater.Core.DataAcquisition import get_east_8_time
-from SystemUpdater.Core.UpdateList import LocalUpgradeDataList
from SystemUpdater.Core.DistUpgradeCache import NotEnoughFreeSpaceError
from SystemUpdater.Core.utils import get_config_patch
+from SystemUpdater.Core.JsonConfigParser import JsonConfig as json_config
+from aptdaemon.enums import ERROR_PACKAGE_DOWNLOAD_FAILED
class NowUpgradeMeta:
"""
Represent the (potentially partial) results of an unattended-upgrades
run
"""
- def __init__(self,
- parent,
- upgrade_groups = [],
- single_pkgs = [],
- version_upgrade = False,
- need_retry = False,
- ):
- self.parent = parent
+ def __init__(self,_upgrade_groups = [],_single_pkgs = []):
+ self.push_content = []
#组列表中包含的包
- self.upgrade_groups = upgrade_groups
+ self.upgrade_groups = _upgrade_groups
#推送的可升级的单包
- self.single_pkgs = single_pkgs
- self.version_upgrade = version_upgrade
- self.need_retry = need_retry
- self.upgrade_content = self.upgrade_groups + self.single_pkgs
-
- #获取当前升级的升级列表
- def _make_groups_list(self,upgrade_data,_upgrade_mode,partial_upgrade_list):
- groups_list = []
- pkg_list = []
-
- #部分升级
- if _upgrade_mode == self.parent.MODE_INSTALL_PARTIAL:
- for elem in partial_upgrade_list:
- #组升级方式
- if elem in upgrade_data.upgrade_groups:
- groups_list.append(elem)
- #单包升级方式
- elif elem in upgrade_data.single_pkgs:
- pkg_list.append(elem)
- else:
- logging.warning("this package(%s) not in selected list",elem)
-
- #全部升级列表
- elif _upgrade_mode == self.parent.MODE_INSTALL_ALL:
- groups_list = upgrade_data.upgrade_groups
- pkg_list = upgrade_data.single_pkgs
-
- return groups_list,pkg_list
-
- def make_upgrade_content(self,content):
- if self.parent.action_mode != self.parent.MODE_INSTALL_SINGLE:
- self.upgrade_groups,self.single_pkgs = self._make_groups_list(self.parent.upgrade_data,self.parent.action_mode,content)
- self.upgrade_content = self.upgrade_groups + self.single_pkgs
- else:
- self.single_pkgs = content
- self.upgrade_content = self.upgrade_groups + self.single_pkgs
+ self.single_pkgs = _single_pkgs
+ self.version_upgrade = True
+
+ def get_content(self):
+ return self.single_pkgs + self.upgrade_groups
class UpdateEssentialItem():
def __init__(self,parent):
@@ -134,7 +98,7 @@ class AptdBaseInformation:
self.error_details = error_details
class InstallBackend():
- INSTALL_OUTPUT_JSON = "/var/lib/kylin-system-updater/json/showdown_install.json"
+ INSTALL_OUTPUT_JSON = "/var/lib/kylin-system-updater/json/requires_upgrade_meta.json"
ACTION_DEFUALT_STATUS = -1
ACTION_UPDATE = 0
@@ -149,20 +113,16 @@ class InstallBackend():
ACTION_INSTALL_SHUTDOWN = 9
ACTION_BACKGROUND_UPGRADE = 10
ACTION_CHECK_BROKEN = 11
+ ACTION_INSTALL_DEB_RESOLVER = 12
MODE_DEFAULT_STATUS = -1
- #1、ACTION_INSTALL 安装的子类
- #部分升级
MODE_INSTALL_PARTIAL = 0
- #全部升级
MODE_INSTALL_ALL = 1
- #系统全盘升级
MODE_INSTALL_SYSTEM = 2
- #后端内部安装包使用 目前 更新配置包和升级本身使用
MODE_INSTALL_SINGLE = 3
+ MODE_INSTALL_STEP = 4
- #2、更新的子类
MODE_UPDATE_CACHE = 0
MODE_UPDATE_ALL = 1
@@ -175,123 +135,76 @@ class InstallBackend():
self.window_main.now_working = action
self.aptd_base = AptdBaseInformation()
+ self.collector = window_main.collector
- self.inhibit_shutdown = InhibitShutdownLock()
+ self.backend_data = window_main.main_meta
+ self.dbus_send = window_main.dbusController
+ self.database = window_main.sqlite3_server
+ self.meta_upgrade = NowUpgradeMeta()
- self.update_essential = UpdateEssentialItem(self)
-
- if self.action == self.ACTION_INSTALL:
+ if self.action != self.ACTION_UPDATE:
self.safe_manager = UpdateSafeManager()
-
- #更新的时候此对象还未生成
- if self.window_main.update_list != None:
- self.upgrade_data = window_main.update_list.upgrade_meta
- else:
- self.upgrade_data = LocalUpgradeDataList()
-
- #要拿到升级列表必须调用_make_upgrade_list
- self.now_upgrade = NowUpgradeMeta(parent=self)
-
- def start(self,partial_upgrade_list = []):
+ self.update_essential = UpdateEssentialItem(self)
+ self.inhibit_shutdown = InhibitShutdownLock()
+ self.scripts = window_main.pm_class
+
+ def start(self,push_content = []):
try:
#安装升级包 首先必须调用ACTION_CHECK_RESOLVER 计算依赖解决方便 标记cache 进行升级
if self.action == self.ACTION_INSTALL or self.action == self.ACTION_DOWNLOADONLY:
- #拿到升级列表
- self.now_upgrade.make_upgrade_content(partial_upgrade_list)
+ self.meta_upgrade.push_content = push_content
+ if self.action_mode == self.MODE_INSTALL_SINGLE:
+ pkgs_install,pkgs_upgrade,pkgs_remove = self.get_mark_from_cache(self.cache)
- pkgs_install,pkgs_upgrade,pkgs_remove,pkgs_downgrade = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode)
- logging.info("INSTALL install:%d , upgrade:%d remove:%d pkgs_downgrade:%d",len(pkgs_install),\
- len(pkgs_upgrade),len(pkgs_remove),len(pkgs_downgrade))
+ self.meta_upgrade.single_pkgs = push_content
+ elif self.action_mode == self.MODE_INSTALL_STEP:
+ self.meta_upgrade.single_pkgs,self.meta_upgrade.upgrade_groups = self.backend_data.classify_content(push_content)
- #当下载数量大于200个包时 就认为属于大版本升级 开启重试机制
- if len(pkgs_install) + len(pkgs_upgrade) > 100:
- logging.info("Open a major version upgrade and Retry mechanism on...")
- self.now_upgrade.version_upgrade = True
-
- #检查是否存在可升级的包
- if len(pkgs_install) == 0 and len(pkgs_upgrade) == 0 and len(pkgs_remove) == 0 and len(pkgs_downgrade) == 0:
- pkgs_install,pkgs_upgrade = self._make_pkgs_list(self.cache,self.upgrade_data.groups_pkgs,self.now_upgrade.upgrade_groups,self.now_upgrade.single_pkgs)
- logging.warning("There is an exception in the update package install = %r upgrade = %r",pkgs_install,pkgs_upgrade)
+ pkgs_install,pkgs_upgrade,pkgs_remove = self.backend_data.get_resolver_upgrade()
+ elif self.action_mode == self.MODE_INSTALL_SYSTEM:
+ self.meta_upgrade.upgrade_groups = ["dist-upgrade"]
+ pkgs_install,pkgs_upgrade,pkgs_remove = self.backend_data.get_resolver_upgrade()
+ else:
+ #单独下载和下载安装同时走此分支
+ self.meta_upgrade.single_pkgs,self.meta_upgrade.upgrade_groups = self.backend_data.classify_content(push_content)
+ pkgs_install,pkgs_upgrade,pkgs_remove = self.backend_data.get_resolver_upgrade()
- # if self.action_mode == self.MODE_INSTALL_SINGLE:
- # logging.warning("MODE_INSTALL_SINGLE install:%s , upgrade:%s remove:%s",str(pkgs_install),str(pkgs_upgrade),str(pkgs_remove))
+ logging.info("INSTALL install:%d , upgrade:%d remove:%d",len(pkgs_install),len(pkgs_upgrade),len(pkgs_remove))
self.update_essential.check_essential(pkgs_remove)
-
- #检查磁盘的状态
- self.check_free_space(self.cache)
- for ul in self.window_main.collector.upgrade_list:
- self.window_main.collector.Upgrade_Process_Msg(self.action, {"appname":ul})
+ for ul in self.collector.upgrade_list:
+ self.collector.Upgrade_Process_Msg(self.action, {"appname":ul})
- if self.action == self.ACTION_INSTALL:
- self.commit(self.action,pkgs_install, pkgs_upgrade, pkgs_remove,pkgs_downgrade)
- elif self.action == self.ACTION_DOWNLOADONLY:
- self._update_to_config(self.now_upgrade,pkgs_install,pkgs_upgrade,pkgs_remove)
- self.commit_only(self.action,pkgs_install, pkgs_upgrade, pkgs_remove,pkgs_downgrade)
-
+ if self.action_mode != self.MODE_INSTALL_SINGLE:
+ self._update_to_config(self.meta_upgrade,pkgs_install,pkgs_upgrade,pkgs_remove)
+
+ if len(pkgs_install) + len(pkgs_upgrade) > 100:
+ logging.info("Open a major version upgrade and Retry mechanism on...")
+ self.meta_upgrade.version_upgrade = True
+
+ if self.action == self.ACTION_DOWNLOADONLY:
+ self.commit_only(self.action,pkgs_install, pkgs_upgrade, pkgs_remove)
+ return
+
+ if self.action_mode != self.MODE_INSTALL_STEP and self.action_mode != self.MODE_INSTALL_SINGLE:
+ #更新前执行脚本的操作
+ for groups in self.meta_upgrade.upgrade_groups:
+ if self.run_steps_script(50,'',groups) == False:
+ raise UpdateBaseError(ERROR_RUN_SCRIPTS_FAILED)
+
+ if self.action_mode == self.MODE_INSTALL_STEP:
+ logging.info("Will be enter to step install model...")
+ self.commit_steps(self.ACTION_DOWNLOADONLY,pkgs_install, pkgs_upgrade, pkgs_remove,0,50)
+ else:
+ self.commit(self.action,pkgs_install, pkgs_upgrade, pkgs_remove)
elif self.action == self.ACTION_INSTALL_SHUTDOWN:
- self.now_upgrade,pkgs_install,pkgs_upgrade,pkgs_remove = self._config_to_upgrade()
+ self.meta_upgrade,pkgs_install,pkgs_upgrade,pkgs_remove = self._config_to_upgrade()
logging.info("ACTION_INSTALL_SHUTDOWN install:%d , upgrade:%d remove:%d",len(pkgs_install),len(pkgs_upgrade),len(pkgs_remove))
# self._start_install_lock()
self.commit(self.action,pkgs_install, pkgs_upgrade, pkgs_remove)
- #计算依赖解决方案
- elif self.action == self.ACTION_CHECK_RESOLVER:
- #被删除包的描述
- raw_description = []
-
- #判断是否配置aptdaemon的限速
- self.window_main.check_conifg_aptdeamon()
-
- if self.action_mode != self.MODE_INSTALL_SYSTEM:
- #获取要升级的组列表
- self.now_upgrade.make_upgrade_content(partial_upgrade_list)
- #获取要升级和安装的包列表
- pkgs_install,pkgs_upgrade = self._make_pkgs_list(self.cache,self.upgrade_data.groups_pkgs,self.now_upgrade.upgrade_groups,self.now_upgrade.single_pkgs)
- #计算解决依赖关系
- self._make_problem_resolver(self.cache,pkgs_install,pkgs_upgrade,self.upgrade_data.adjust_pkgs)
- pkgs_install,pkgs_upgrade,pkgs_remove,pkgs_downgrade = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode)
- else:
- # 使用全盘升级 全盘使用dist-upgrade
- if self.cache.get_changes():
- self.cache.clear()
- self.cache._depcache.upgrade(True)
- pkgs_install,pkgs_upgrade,pkgs_remove,pkgs_downgrade = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode)
-
- logging.warning("ProblemResolver of the deletion package list:%s",str(pkgs_remove))
- self.update_essential.check_white(pkgs_remove)
- logging.info("RESOLVER install:%d , upgrade:%d remove:%d pkgs_downgrade:%d",len(pkgs_install),len(pkgs_upgrade),\
- len(pkgs_remove),len(pkgs_downgrade))
- is_remove_pkgs = len(pkgs_remove) != 0
-
- # 数据上报
- self.window_main.collector.Generate_Msg(self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs, self.action_mode)
- errorCode = ""
- if is_remove_pkgs:
- errorCode = _("Need remove pkgs: ")+", ".join(pkgs_remove)
- for ul in self.window_main.collector.upgrade_list:
- self.window_main.collector.Upgrade_Process_Msg(self.action, {"appname":ul, "status":is_remove_pkgs, "errorCode":errorCode})
-
- #补充删除包的描述信息,删除描述
- delete_desc = []
- for pkg in pkgs_remove:
- pkg_obj = self.cache[pkg]
- raw_description.append(getattr(pkg_obj.candidate, "summary", ''))
- delete_desc.append('')
-
- if self.action_mode != self.MODE_INSTALL_SYSTEM:
- self.window_main.dbusController.UpdateDependResloveStatus(True,is_remove_pkgs,pkgs_remove,raw_description,delete_desc,'','')
- else:
- self.window_main.dbusController.DistupgradeDependResloveStatus(True,is_remove_pkgs,pkgs_remove,raw_description,delete_desc,'','')
-
- self._action_done(self.action,False,True,'','')
-
- if is_remove_pkgs:
- threading_emulate = threading.Thread(target=self._emulate_calcul_delete,args=((pkgs_upgrade + pkgs_install),))
- threading_emulate.start()
-
#修复未满足的依赖关系 与apt-get -f install匹配
elif self.action == self.ACTION_CHECK_BROKEN:
try:
@@ -317,7 +230,7 @@ class InstallBackend():
pkg_obj = self.cache[pkg]
raw_description.append(getattr(pkg_obj.candidate, "summary", ''))
- self.window_main.dbusController.UpdateFixBrokenStatus(True,True,pkgs_remove,raw_description,delete_desc,'','')
+ self.dbus_send.UpdateFixBrokenStatus(True,True,pkgs_remove,raw_description,delete_desc,'','')
self._action_done(self.action,False,True,'','')
elif self.action == self.ACTION_FIX_BROKEN:
@@ -331,13 +244,13 @@ class InstallBackend():
#卸载包
elif self.action == self.ACTION_REMOVE_PACKAGES:
self._start_install_lock(_("Kylin System Updater"))
- self.purge_packages(partial_upgrade_list)
+ self.purge_packages(push_content)
elif self.action == self.ACTION_CLEAN:
self.clean()
#更新cache
elif self.action == self.ACTION_UPDATE:
#检查依赖之前 判断是否需要重启aptdeamon 目前为了生效限速功能
- self.window_main.check_conifg_aptdeamon()
+ self.window_main.check_config_aptdeamon()
self.update()
except UpdateBaseError as excep:
self._action_done(self.action,True,False,excep.header,excep.desc,excep.code)
@@ -347,31 +260,141 @@ class InstallBackend():
logging.error(e)
traceback.print_exc()
- def start_alone(self,partial_upgrade_list = [],_is_install = False, caller=''):
+ def start_resolver(self,push_content):
+ try:
+ #被删除包的描述
+ raw_description = []
+ total_remove = []
+
+ if self.action_mode != self.MODE_INSTALL_SYSTEM:
+ all_install,all_upgrade = self.backend_data.get_push_pkgs(push_content)
+ logging.info("ALLs install:%d , upgrade:%d",len(all_install),len(all_upgrade))
+
+ self._make_problem_resolver(self.cache,all_install,all_upgrade)
+ pkgs_install,pkgs_upgrade,pkgs_remove = self.get_mark_from_cache(self.cache)
+ total_remove += pkgs_remove
+
+ self.backend_data.resolver_groups(pkgs_install,pkgs_upgrade,pkgs_remove)
+ self.check_free_space(self.cache)
+
+ #分步更新处理过程
+ if self.action_mode == self.MODE_INSTALL_STEP:
+ steps_reboot = False
+ for step_name in self.backend_data.get_steps():
+ step_install,step_upgrade = self.backend_data.get_steps_pkgs(step_name)
+ logging.info("Steps(%s): install:%d , upgrade:%d",step_name,len(step_install),len(step_upgrade))
+ self._make_problem_resolver(self.cache,step_install,step_upgrade)
+
+ step_install,step_upgrade,step_remove = self.get_mark_from_cache(self.cache)
+ logging.info("RESOLVER(%s):Steps install:%d , upgrade:%d remove:%d ",step_name,len(step_install),\
+ len(step_upgrade),len(step_remove))
+
+ if len(step_install) == 0 and len(step_upgrade) == 0 and len(step_remove) == 0:
+ logging.warning("Steps(%s) This update cannot detect the upgradeable package.",step_name)
+
+ self.backend_data.resolver_steps(step_name,step_install,step_upgrade,step_remove)
+
+ total_remove += step_remove
+
+ self.backend_data.steps_queue.insert(0,step_name)
+
+ steps_reboot = self.backend_data.check_steps_reboot(step_name)
+ if steps_reboot == True:
+ break
+
+ if steps_reboot == False:
+ self.backend_data.steps_queue.insert(0,self.backend_data.resolver_name)
+ else:
+ # 使用全盘升级 类似 apt dist-upgrade
+ if self.cache.get_changes():
+ self.cache.clear()
+ self.cache._depcache.upgrade(True)
+ pkgs_install,pkgs_upgrade,pkgs_remove = self.get_mark_from_cache(self.cache)
+ self.backend_data.resolver_groups(pkgs_install,pkgs_upgrade,pkgs_remove)
+
+ self.check_free_space(self.cache)
+
+ total_remove += pkgs_remove
+
+ #可能存在重复,去除
+ total_remove = list(set(total_remove))
+
+ logging.warning("ProblemResolver of the deletion package list:%s",str(total_remove))
+ self.update_essential.check_white(total_remove)
+
+ logging.info("RESOLVER:ALL install:%d , upgrade:%d remove:%d ",len(pkgs_install),len(pkgs_upgrade),\
+ len(total_remove))
+
+ is_remove_pkgs = len(total_remove) != 0
+
+ # 数据上报
+ self.collector.Generate_Msg(self.meta_upgrade.get_content(), self.action_mode)
+ errorCode = ""
+ if is_remove_pkgs:
+ errorCode = _("Need remove pkgs: ")+", ".join(total_remove)
+ for ul in self.collector.upgrade_list:
+ self.collector.Upgrade_Process_Msg(self.action, {"appname":ul, "status":is_remove_pkgs, "errorCode":errorCode})
+
+ #补充删除包的描述信息,删除描述
+ delete_desc = []
+ for pkg in total_remove:
+ pkg_obj = self.cache[pkg]
+ raw_description.append(getattr(pkg_obj.candidate, "summary", ''))
+ delete_desc.append('')
+
+ if self.action_mode != self.MODE_INSTALL_SYSTEM:
+ self.dbus_send.UpdateDependResloveStatus(True,is_remove_pkgs,total_remove,raw_description,delete_desc,'','')
+ else:
+ self.dbus_send.DistupgradeDependResloveStatus(True,is_remove_pkgs,total_remove,raw_description,delete_desc,'','')
+
+ self._action_done(self.action,False,True,'','')
+
+ if is_remove_pkgs:
+ threading_emulate = threading.Thread(target=self._emulate_calcul_delete,args=((pkgs_upgrade + pkgs_install),))
+ threading_emulate.start()
+
+ except UpdateBaseError as excep:
+ self.dbus_send.InstallDetectStatus(False,get_error_code_from_enum(excep.code))
+ self._action_done(self.action,True,False,excep.header,excep.desc,excep.code)
+ except UpdateProgressExit as excep:
+ pass
+ except Exception as e:
+ logging.error(e)
+ traceback.print_exc()
+
+ def start_alone(self,push_content = [],_is_install = False, caller=''):
# 安装本地deb包的接口
if self.action == self.ACTION_INSTALL_DEB:
try:
self._start_install_lock(caller=caller)
- self.install_deb(install_path = partial_upgrade_list, install_force = _is_install)
+ self.install_deb(install_path = push_content, install_force = _is_install)
+ except Exception as e:
+ logging.error(str(e))
+ elif self.action == self.ACTION_INSTALL_DEB_RESOLVER:
+ try:
+ self._make_problem_resolver(self.cache,push_content,[])
+ pkgs_install,pkgs_upgrade,pkgs_remove = self.get_mark_from_cache(self.cache)
+ self._start_install_lock(caller=caller)
+ self.commit(self.ACTION_INSTALL,pkgs_install,pkgs_upgrade,pkgs_remove)
except Exception as e:
logging.error(str(e))
# 安装在线包的接口
elif self.action == self.ACTION_BACKGROUND_UPGRADE:
try:
- pkgs_install = [ str(pkg) for pkg in partial_upgrade_list]
+ pkgs_install = [ str(pkg) for pkg in push_content]
logging.info("Install deb package, open cache")
cache = Cache()
for pkg_name in pkgs_install:
if pkg_name not in cache:
if "=" not in pkg_name or ("=" in pkg_name and pkg_name.split("=")[0] not in cache):
# 没找到包或格式不正确
- self.window_main.dbusController.UpdateInstallFinished(False, pkgs_install, "'"+pkg_name+"' is not in cache", "")
+ self.dbus_send.UpdateInstallFinished(False, pkgs_install, "'"+pkg_name+"' is not in cache", "")
return
self._start_install_lock(caller=caller)
self.commit(self.ACTION_INSTALL,pkgs_install,[],[])
except Exception as e:
logging.error(str(e))
- self.window_main.dbusController.UpdateInstallFinished(False, pkgs_install, str(e), "")
+ self.dbus_send.UpdateInstallFinished(False, pkgs_install, str(e), "")
def update(self):
"""Run a update to refresh the package list"""
@@ -420,19 +443,19 @@ class InstallBackend():
pass
return pkgs_install,pkgs_upgrade,pkgs_remove
- #从cache中拿到标记的列表
- def _get_mark_from_cache(self,cache,_adjust_pkgs,upgrade_mode):
+ def get_mark_from_cache(self,cache):
+ '''从cache中拿到标记的升级新装和删除的包
+
+ 入参:
+ cache - 当前cache
+ 出参:
+ pkgs_install - 当前要安装的包列表
+ pkgs_upgrade - 当前要安装的包列表
+ pkgs_remove - 当前要卸载的包列表
+ '''
pkgs_install = []
pkgs_upgrade = []
pkgs_remove = []
- pkgs_downgrade = []
-
- #全盘升级不做任何的调整
- if upgrade_mode == self.MODE_INSTALL_SYSTEM or upgrade_mode == self.MODE_INSTALL_SINGLE:
- adjust_pkgs = []
- else:
- #获取调整包列表 去掉版本号
- adjust_pkgs = [i.split("=")[0] for i in _adjust_pkgs]
for pkg in cache:
try:
@@ -440,46 +463,16 @@ class InstallBackend():
pkgname = pkg.name
if pkg.is_auto_installed:
pkgname += "#auto"
- if pkg.name in adjust_pkgs:
- pkgs_install.append(_adjust_pkgs[adjust_pkgs.index(pkg.name)])
+ pkgs_install.append(pkgname)
else:
pkgs_install.append(pkgname)
elif pkg.marked_upgrade:
- if pkg.name in adjust_pkgs:
- pkgs_upgrade.append(_adjust_pkgs[adjust_pkgs.index(pkg.name)])
- else:
pkgs_upgrade.append(pkg.name)
elif pkg.marked_delete:
pkgs_remove.append(pkg.name)
- elif pkg.marked_downgrade:
- pkgs_downgrade.append(pkg.name+'='+pkg.candidate.source_version)
except KeyError:
pass
- return pkgs_install,pkgs_upgrade,pkgs_remove,pkgs_downgrade
-
- #获取当前升级的升级列表
- def _make_groups_list(self,upgrade_data,_upgrade_mode,partial_upgrade_list):
- groups_list = []
- pkg_list = []
-
- #部分升级
- if _upgrade_mode == self.MODE_INSTALL_PARTIAL:
- for elem in partial_upgrade_list:
- #组升级方式
- if elem in upgrade_data.upgrade_groups:
- groups_list.append(elem)
- #单包升级方式
- elif elem in upgrade_data.single_pkgs:
- pkg_list.append(elem)
- else:
- logging.warning("this package(%s) not in selected list",elem)
-
- #全部升级列表
- elif _upgrade_mode == self.MODE_INSTALL_ALL:
- groups_list = upgrade_data.upgrade_groups
- pkg_list = upgrade_data.single_pkgs
-
- return groups_list,pkg_list
+ return pkgs_install,pkgs_upgrade,pkgs_remove
#从本地中获取本次升级需要升级的包 部分升级和全部升级使用 全盘升级不适用
def _make_pkgs_list(self,cache,groups_pkgs,groups_list,pkg_list):
@@ -542,27 +535,15 @@ class InstallBackend():
version = release = None
return name, version, release
- #将获取本次升级的包 进行计算依赖关系 解决依赖问题
- def _make_problem_resolver(self,cache,pkgs_install = [],pkgs_upgrade = [],adjust_pkgs = []):
+ def _make_problem_resolver(self,cache,pkgs_install = [],pkgs_upgrade = []):
try:
- logging.info("ProblemResolver install:%d , upgrade:%d",len(pkgs_install),len(pkgs_upgrade))
logging.info("Start calculating dependencies...")
- #actiongroup 可以加速计算依赖关系 计算花费的时间将大幅度缩减
with cache.actiongroup():
if cache.get_changes():
cache.clear()
resolver = apt.cache.ProblemResolver(cache)
- for pkg_name, pkg_ver, pkg_rel in [self._split_package_id(pkg)
- for pkg in adjust_pkgs]:
- try:
- pkg = cache[pkg_name]
- pkg.candidate = pkg.versions[pkg_ver]
- except KeyError:
- logging.warning("The version %s of %s isn't available",pkg_ver, pkg_name)
- continue
-
for pkg in pkgs_upgrade + pkgs_install:
pkg_cache = cache[pkg]
if pkg_cache.is_upgradable == False and pkg_cache.is_installed == True:
@@ -630,103 +611,161 @@ class InstallBackend():
def _send_error_code(self,error_code):
if error_code == ERROR_NOT_DISK_SPACE:
- self.window_main.dbusController.InstallDetectStatus(False,error_code)
+ self.dbus_send.InstallDetectStatus(False,error_code)
- def _self_upgrade_finished(self,success,error_string='',error_desc=''):
+ def _self_upgrade_finished(self,success,error_string='',error_desc='',error_code=''):
if success:
- if self.window_main.configs_cover.getWithDefault("SystemStatusCover", "priority_upgrade_restart", False,True) == True:
- error_string = get_error_string_from_enum(PRIORITY_UPGRADE_SUCCCESSED)
- if self.window_main.APTD_PKG_NAME in self.now_upgrade.upgrade_content:
- self.window_main.dbusController.UpdateDetectFinished(False,[self.window_main.BACKEND_PKG_NAME],error_string,'')
- self.window_main.dbusController.make_aptdeamon_restart()
-
- #当单包升级的时候 升级本身时,让程序退出,再重新启动
- if self.window_main.FRONTEND_PKG_NAME in self.now_upgrade.upgrade_content:
- self.window_main.dbusController.UpdateDetectFinished(False,[self.window_main.BACKEND_PKG_NAME],error_string,'')
-
- #当单包升级的时候 升级本身时,让程序退出,再重新启动
- if self.window_main.BACKEND_PKG_NAME in self.now_upgrade.upgrade_content:
- self.window_main.dbusController.UpdateDetectFinished(False,[self.window_main.BACKEND_PKG_NAME],error_string,'')
- #升级本身完成后 退出 有systemd 来进行重启服务
- self.window_main.dbusController.Quit(None)
- return
+ restart_ui = False
- #当单包升级的时候 升级本身时,让程序退出,再重新启动
- if self.window_main.GROUPS_PKG_NAME in self.now_upgrade.upgrade_content:
- self.window_main.start_available()
- else:
+ channel_config = json_config().getWithDefault("update_channel_upgrade",default = {})
+
+ restart_list = channel_config.get("restart_service_list",[self.window_main.APTD_PKG_NAME,self.window_main.BACKEND_PKG_NAME])
+ notify_list = channel_config.get("restart_panel_list",[self.window_main.FRONTEND_PKG_NAME])
+
+ error_string = get_error_string_from_enum(PRIORITY_UPGRADE_SUCCCESSED)
+
+ if (self.window_main.APTD_PKG_NAME in self.meta_upgrade.get_content() and self.window_main.BACKEND_PKG_NAME not in self.meta_upgrade.get_content()) \
+ and self.window_main.APTD_PKG_NAME in restart_list:
+ self.dbus_send.make_aptdeamon_restart()
+
+ if self.window_main.FRONTEND_PKG_NAME in self.meta_upgrade.get_content() and \
+ self.window_main.FRONTEND_PKG_NAME in notify_list:
+ self.dbus_send.UpdateDetectFinished(False,[self.window_main.BACKEND_PKG_NAME],error_string,'')
+ restart_ui = True
+
+ # 异常情况 需要强制重启ui提示
+ if "force_restart_ui" in notify_list:
+ self.dbus_send.UpdateDetectFinished(False,[self.window_main.BACKEND_PKG_NAME],error_string,'')
+ restart_ui = True
+
+ if self.window_main.BACKEND_PKG_NAME in self.meta_upgrade.get_content() and \
+ self.window_main.BACKEND_PKG_NAME in restart_list:
+ if restart_ui == False:
+ self.window_main.configs_uncover.setValue("SystemStatus","reboot_update",str(True))
+ self.dbus_send.Quit(None)
+ return
+
+ if restart_ui != True:
self.window_main.start_available()
else:
- self.window_main.dbusController.UpdateDetectFinished(False,[''],get_error_string_from_enum(ERROR_UPDATE_DEFAULT_FAILED),\
+ self.dbus_send.InstallDetectStatus(False,get_error_code_from_enum(error_code))
+ self.dbus_send.UpdateDetectFinished(False,[''],get_error_string_from_enum(ERROR_UPDATE_DEFAULT_FAILED),\
error_string +' '+error_desc)
+ def run_steps_script(self,progress,last_steps,steps):
+ if progress == 50:
+ script_list = self.backend_data.get_pre_script(steps)
+ for scr in script_list:
+ if self.scripts.run_plugin(scr) == False:
+ return True
+ elif progress == 100:
+ script_list = self.backend_data.get_post_script(last_steps)
+ for scr in script_list:
+ if self.scripts.run_plugin(scr) == False:
+ return True
+ else:
+ script_list = self.backend_data.get_post_script(last_steps) + self.backend_data.get_pre_script(steps)
+ for scr in script_list:
+ if self.scripts.run_plugin(scr) == False:
+ return True
+ return True
+
+ def _steps_done(self):
+ #分步更新任务队列
+ if self.backend_data.steps_queue != []:
+ now_steps = self.backend_data.steps_queue.pop()
+ progress_begin,progress_end = self.backend_data.get_progress(now_steps)
+ pkgs_install,pkgs_upgrade,pkgs_remove = self.backend_data.get_resolver_steps(now_steps)
+
+ if self.run_steps_script(progress_begin,self.backend_data.last_task,now_steps) == False:
+ self._action_done(self.action,False,False,get_error_string_from_enum(ERROR_RUN_SCRIPTS_FAILED),\
+ get_error_description_from_enum(ERROR_RUN_SCRIPTS_FAILED))
+ return
+
+ #记录上一次的任务
+ self.backend_data.last_task = now_steps
+
+ mid_info = self.backend_data.get_mid_notify(now_steps)
+ if mid_info != '':
+ self.dbus_send.NotifyStepsInstalled(True,mid_info)
+
+ logging.info("INSTALL(%s) install:%d , upgrade:%d remove:%d",now_steps,len(pkgs_install),len(pkgs_upgrade),len(pkgs_remove))
+ self.commit_steps(self.action,pkgs_install, pkgs_upgrade, pkgs_remove,\
+ progress_begin,progress_end,self.backend_data.steps_queue == [])
+ return
+
#调用aptdeamon结束之后处理的地方 不管是出错还是正常都在此处理
- def _action_done(self, action, is_cancelled,success, error_string='',error_desc='',error_code=''):
- #后端的状态 到空闲状态
+ def _action_done(self, action, is_cancelled,success, error_string='',error_desc='',error_code=''):
self.window_main.now_working = self.ACTION_DEFUALT_STATUS
- #升级完成后走的分支
if action == self.ACTION_INSTALL:
- false_num = 0
- self.safe_manager.reset_safe()
- self._release_install_lock()
+ #整个安装执行完毕 退出
self._send_error_code(error_code)
-
- if self.action_mode == self.MODE_INSTALL_SINGLE:
- self._self_upgrade_finished(success,error_string,error_desc)
- else:
- if self.now_upgrade.version_upgrade == True and self.now_upgrade.need_retry == True and success == False:
- #增加重试次数的限制
- if self.window_main.retry_limit != 0:
- logging.warning("Retry the upgrade and installaton(%s) and retry number: %d",self.now_upgrade.upgrade_content,self.window_main.retry_limit)
- self.window_main.start_install(self.action_mode,True,self.now_upgrade.upgrade_content)
- self.window_main.retry_limit = self.window_main.retry_limit - 1
- return
- try:
- false_num = self._make_insert_info(success,is_cancelled,self.now_upgrade,error_string,error_desc)
- except Exception as e:
- logging.error(e)
+ self.exit_installed()
+
+ if self.action_mode == self.MODE_INSTALL_STEP:
+ if self.run_steps_script(100,self.backend_data.last_task,'') == False:
+ error_string = get_error_string_from_enum(ERROR_RUN_SCRIPTS_FAILED)
+ error_desc = get_error_description_from_enum(ERROR_RUN_SCRIPTS_FAILED)
+ success = False
- if success == False:
- logging.info("The number of failed installations or upgrades is %d",false_num)
+ #弹窗的处理过程 在全部安装时不会进行弹窗
+ if success and self.backend_data.last_task != self.backend_data.resolver_name:
+ post_info = self.backend_data.get_post_notify()
+ if post_info != '':
+ self.dbus_send.PopupStepsInstalled(True,post_info)
+ self.dbus_send.RebootLogoutRequired("reboot")
+
+ if success == False or self.backend_data.last_task == self.backend_data.resolver_name:
+ self.database.insert_info(action,self.meta_upgrade.single_pkgs,\
+ self.meta_upgrade.upgrade_groups,[],success,error_string,error_desc)
- #修复bug 所有的包都安装成功了,但是却返回的失败,计算这种状况 从失败切换到安装成功的状态
- #这个 为True的很低 大多数为False 只有当系统中apt 出现问题时 才会复现这种问题
- if success == False and false_num == 0 and self.now_upgrade.upgrade_content != []:
- logging.warning("Special Case switch success status from False to True...")
- # success = True
+ self.dbus_send.InstallDetectStatus(False,get_error_code_from_enum(error_code))
+ self.dbus_send.UpdateInstallFinished(success,self.meta_upgrade.get_content(),error_string,error_desc)
+
+ self.window_main.refresh_cache()
+
+ elif self.action_mode == self.MODE_INSTALL_SINGLE:
+ self._self_upgrade_finished(success,error_string,error_desc,error_code)
+ else:
+ #下载重试机制的判断
+ if self.meta_upgrade.version_upgrade == True and success == False and error_code == ERROR_PACKAGE_DOWNLOAD_FAILED:
+ if self.dbus_send.check_connectivity_pro() == True:
+ if self.window_main.retry_limit != 0:
+ logging.warning("Retry the upgrade and installaton and retry number: %d",self.window_main.retry_limit)
+ self.window_main.start_install(self.action_mode,True,self.meta_upgrade.push_content)
+ self.window_main.retry_limit = self.window_main.retry_limit - 1
+ return
+
+ #更新完毕后执行脚本的操作
+ for groups in self.meta_upgrade.upgrade_groups:
+ if self.run_steps_script(100,groups,'') == False:
+ error_string = get_error_string_from_enum(ERROR_RUN_SCRIPTS_FAILED)
+ error_desc = get_error_description_from_enum(ERROR_RUN_SCRIPTS_FAILED)
+ success = False
+
+ self.database.insert_info(action,self.meta_upgrade.single_pkgs,self.meta_upgrade.upgrade_groups\
+ ,[],success,error_string,error_desc)
+ self.dbus_send.InstallDetectStatus(False,get_error_code_from_enum(error_code))
+ self.dbus_send.UpdateInstallFinished(success,self.meta_upgrade.get_content(),error_string,error_desc)
if success:
- #当组列表为空时 表示现在的单独进行安装某些包或卸载,不发信号到控制面板
- #升级完成后从升级列表删除
- for groups in self.now_upgrade.upgrade_groups:
- self.upgrade_data.upgrade_groups.remove(groups)
-
- for pkg in self.now_upgrade.single_pkgs:
- self.upgrade_data.single_pkgs.remove(pkg)
-
- error_string = ''
- error_desc = ''
-
- self.window_main.dbusController.UpdateInstallFinished(success,self.now_upgrade.upgrade_content,error_string,error_desc)
-
- if success:
- self.window_main.dbusController.CheckRebootRequired("self")
- #安装完成之后 更新一次cache
+ self.backend_data.pop(self.meta_upgrade.get_content())
+ self.dbus_send.CheckRebootRequired("self")
logging.info("Install or Upgrade successful, so Now update Cache...")
self.window_main.refresh_cache()
-
+
elif action == self.ACTION_INSTALL_SHUTDOWN:
# self._release_install_lock()
self._send_error_code(error_code)
#插入数据库
- self.window_main.sqlite3_server.insert_info(self.ACTION_INSTALL,self.now_upgrade.single_pkgs,\
- self.now_upgrade.upgrade_groups,[],success,error_string,error_desc)
+ self.database.insert_info(self.ACTION_INSTALL,self.meta_upgrade.single_pkgs,\
+ self.meta_upgrade.upgrade_groups,[],success,error_string,error_desc)
if success == True:
#当升级完成时 将手动和自动安装的标志位全部清空
self.window_main.install_mode.install_finished()
- self.window_main.dbusController.UpdateInstallFinished(success,self.now_upgrade.upgrade_content,error_string,error_desc)
+ self.dbus_send.UpdateInstallFinished(success,self.meta_upgrade.get_content(),error_string,error_desc)
#释放锁 允许关机
if self.window_main.install_mode.inhibit_lock != None:
@@ -735,33 +774,25 @@ class InstallBackend():
else:
logging.error("Install Packages Finished and Releasing the shutdown lock Failed...")
#升级本身完成后 来释放关机锁
- self.window_main.dbusController.Quit(None)
+ self.dbus_send.Quit(None)
elif action == self.ACTION_CHECK_RESOLVER:
if success == False:
- self.window_main.sqlite3_server.insert_info(self.action_mode,self.now_upgrade.single_pkgs,\
- self.now_upgrade.upgrade_groups,[],success,error_string,error_desc)
+ self.database.insert_info(self.action_mode,self.meta_upgrade.single_pkgs,\
+ self.meta_upgrade.upgrade_groups,[],success,error_string,error_desc)
if self.action_mode != self.MODE_INSTALL_SYSTEM:
- self.window_main.dbusController.UpdateDependResloveStatus(success,False,[''],[''],[''],error_string,error_desc)
+ self.dbus_send.UpdateDependResloveStatus(success,False,[''],[''],[''],error_string,error_desc)
else:
- self.window_main.dbusController.DistupgradeDependResloveStatus(success,False,[''],[''],[''],error_string,error_desc)
+ self.dbus_send.DistupgradeDependResloveStatus(success,False,[''],[''],[''],error_string,error_desc)
elif action == self.ACTION_DOWNLOADONLY:
- if self.now_upgrade.version_upgrade == True and self.now_upgrade.need_retry == True and success == False:
- #增加重试次数的限制
- if self.window_main.retry_limit != 0:
- logging.warning("Retry the upgrade and installaton(%s) and retry number: %d",self.now_upgrade.upgrade_content,self.window_main.retry_limit)
- self.window_main.start_install(self.action_mode,True,self.now_upgrade.upgrade_content)
- self.window_main.retry_limit = self.window_main.retry_limit - 1
- return
-
if success == True and self.action_mode == self.MODE_INSTALL_PARTIAL:
- self.window_main.install_mode.tmp_content += self.now_upgrade.upgrade_content
+ self.window_main.install_mode.tmp_content += self.meta_upgrade.get_content()
if success == False:
- self.window_main.sqlite3_server.insert_info(self.action_mode,self.now_upgrade.single_pkgs,\
- self.now_upgrade.upgrade_groups,[],success,error_string,error_desc)
+ self.database.insert_info(self.action_mode,self.meta_upgrade.single_pkgs,\
+ self.meta_upgrade.upgrade_groups,[],success,error_string,error_desc)
#如果下载成功 就标志需要 安装重启
if success == True:
@@ -770,7 +801,7 @@ class InstallBackend():
self.window_main.install_mode.set_shutdown_install(success)
- self.window_main.dbusController.UpdateDownloadFinished(success,self.now_upgrade.upgrade_content,error_string,error_desc)
+ self.dbus_send.UpdateDownloadFinished(success,self.meta_upgrade.get_content(),error_string,error_desc)
elif action == self.ACTION_UPDATE and self.action_mode == self.MODE_UPDATE_ALL:
if success == False:
@@ -790,21 +821,24 @@ class InstallBackend():
#开始生成列表
self.window_main.start_available()
else:
- self.window_main.dbusController.UpdateDetectFinished(success,[''],get_error_string_from_enum(ERROR_UPDATE_DEFAULT_FAILED),\
+ self.dbus_send.InstallDetectStatus(False,get_error_code_from_enum(error_code))
+ self.dbus_send.UpdateDetectFinished(False,[''],get_error_string_from_enum(ERROR_UPDATE_DEFAULT_FAILED),\
error_string +' '+error_desc)
- self.window_main.sqlite3_server.insert_into_display("check_time",get_east_8_time()[0:-4])
+ self.database.insert_into_display("check_time",get_east_8_time()[0:-4])
elif action == self.ACTION_UPDATE and self.action_mode == self.MODE_UPDATE_CACHE:
- self.window_main.dbusController.UpdateDetectFinished(success,[''],error_string,error_desc)
+ self.dbus_send.InstallDetectStatus(False,get_error_code_from_enum(error_code))
+ self.dbus_send.UpdateDetectFinished(success,[''],error_string,error_desc)
elif action == self.ACTION_FIX_BROKEN:
- self.window_main.dbusController.FixBrokenStatusChanged(True,success,100,'',error_string,error_desc)
+ self.dbus_send.FixBrokenStatusChanged(True,success,100,'',error_string,error_desc)
logging.warning("fix broken packages is complete...")
if success:
logging.info("Fix broken packages is complete to success...")
self.window_main.start_available()
else:
- self.window_main.dbusController.UpdateDetectFinished(success,[''],\
+ self.dbus_send.InstallDetectStatus(False,get_error_code_from_enum(ERROR_NOT_FIX_SYSTEM))
+ self.dbus_send.UpdateDetectFinished(success,[''],\
get_error_string_from_enum(ERROR_NOT_FIX_SYSTEM),error_string+' '+error_desc)
logging.error("fix broken packages is complete to failed...")
@@ -816,32 +850,35 @@ class InstallBackend():
elif action == self.ACTION_REMOVE_PACKAGES:
self._release_install_lock()
- self.window_main.dbusController.PurgePackagesFinished(success,error_string,error_desc)
-
- elif action == self.ACTION_INSTALL_DEB:
+ # self.dbus_send.PurgePackagesFinished(success,error_string,error_desc," ".join(self.window_main.sqlite3_server.current_purge_pkgs))
+ self.dbus_send.PurgePackagesFinished(success,error_string,error_desc)
+
+ elif action == self.ACTION_INSTALL_DEB or action == self.ACTION_INSTALL_DEB_RESOLVER:
self._release_install_lock()
- #FIXME: '\r\n: \r\n\r\n'就认为是验证失败
if success == False and '\r\n: \r\n\r\n' in self.aptd_base.error_details:
error_string = _("Package validation failed and installation was rejected.")
error_desc = ''
- self.window_main.dbusController.InstalldebFinished(success,error_string,error_desc)
- UpdateMsg = {}
- if success:
- status = 'success'
- UpdateMsg.update({"errorCode":" "})
- else:
- status = 'failed'
- UpdateMsg.update({"errorCode":str(error_string+" "+error_desc)})
- #apt发送数据
- if self.window_main.configs_uncover.getWithDefault("SystemStatus", "upload_installer_log", False) == True:
-
- UpdateMsg.update({"appname":str(self.window_main.deb_obj.get("debname","None").split("_")[0])})
- UpdateMsg.update({"source":str(self.window_main.deb_obj.get("source","kylin-system-updater"))})
- UpdateMsg.update({"status":str(status)})
- UpdateMsg.update({"new_version":str(self.window_main.deb_obj.get("debname","None").split("_")[1])})
- UpdateMsg.update({"old_version":str(self.window_main.deb_obj.get("old_version","None"))})
- self.window_main.collector.Upgrade_Process_Msg(self.action, UpdateMsg.copy())
- self.window_main.deb_obj = {}
+ if error_code != None and str(error_code) != 'error-dep-resolution-failed':
+ if error_desc != '':
+ error_string = ",".join((error_string,error_desc))
+ self.dbus_send.InstalldebFinished(success,error_string,'')
+ UpdateMsg = {}
+ if success:
+ status = 'success'
+ UpdateMsg.update({"errorCode":" "})
+ else:
+ status = 'failed'
+ UpdateMsg.update({"errorCode":str(error_string+" "+error_desc)})
+ #apt发送数据
+ if self.window_main.configs_uncover.getWithDefault("SystemStatus", "upload_installer_log", False) == True:
+
+ UpdateMsg.update({"appname":str(self.window_main.deb_obj.get("debname","None").split("_")[0])})
+ UpdateMsg.update({"source":str(self.window_main.deb_obj.get("source","kylin-system-updater"))})
+ UpdateMsg.update({"status":str(status)})
+ UpdateMsg.update({"new_version":str(self.window_main.deb_obj.get("debname","None").split("_")[1])})
+ UpdateMsg.update({"old_version":str(self.window_main.deb_obj.get("old_version","None"))})
+ self.collector.Upgrade_Process_Msg(self.action, UpdateMsg.copy())
+ self.window_main.deb_obj = {}
elif action == self.ACTION_BACKGROUND_UPGRADE:
self._release_install_lock()
UpdateMsg = {}
@@ -849,22 +886,38 @@ class InstallBackend():
status = 'success'
else:
status = 'failed'
- self.window_main.collector.Generate_Msg(self.window_main.collector.background_list, self.action_mode)
- for bl in self.window_main.collector.background_list:
- pkg = self.window_main.collector.cache[bl]
+ self.collector.Generate_Msg(self.collector.background_list, self.action_mode)
+ for bl in self.collector.background_list:
+ pkg = self.collector.cache[bl]
UpdateMsg.update({"appname":str(bl)})
UpdateMsg.update({"source":"Kylin Background upgrade"})
UpdateMsg.update({"status":str(status)})
UpdateMsg.update({"errorCode":str(error_string+" "+error_desc)})
- if self.window_main.collector.background_version[bl]:
- UpdateMsg.update({"old_version":self.window_main.collector.background_version[bl]})
- UpdateMsg.update({"new_version":self.window_main.collector.cache[bl].candidate.source_version})
- # self.window_main.collector.Upgrade_Process_Msg(self.action, UpdateMsg.copy())
+ if self.collector.background_version[bl]:
+ UpdateMsg.update({"old_version":self.collector.background_version[bl]})
+ UpdateMsg.update({"new_version":self.collector.cache[bl].candidate.source_version})
+ # self.collector.Upgrade_Process_Msg(self.action, UpdateMsg.copy())
- self.window_main.dbusController.UpdateInstallFinished(success,self.now_upgrade.upgrade_content,error_string,error_desc)
+ self.dbus_send.UpdateInstallFinished(success,self.meta_upgrade.get_content(),error_string,error_desc)
+
+ def entering_installed(self):
+ '''进入安装的状态
+ 1、禁止关机的锁
+ 2、关闭安全机制
+ '''
+ logging.info("The process is now in the installtion phase")
+ # self.safe_manager.shutdown_safe()
+ self._start_install_lock(_("Kylin System Updater"))
+ def exit_installed(self):
+ '''退出安装的状态
+ 1、释放禁止关机的锁
+ 2、还原安全的配置
+ '''
+ # self.safe_manager.reset_safe()
+ self._release_install_lock()
- def _start_install_lock(self, caller='Kylin System Updater'):
+ def _start_install_lock(self, caller='kylin-system-updater'):
self.window_main.configs_uncover.setValue("SystemStatus","abnormal_reboot",str(True))
self.inhibit_shutdown.lock(caller=caller)
@@ -880,22 +933,24 @@ class InstallBackend():
run_cmd = ["/bin/plymouth","system-update",tmp]
subprocess.call(run_cmd)
- def _update_to_config(self,now_upgrade,pkgs_install,pkgs_upgrade,pkgs_remove):
- output_upgrade = {}
+ def _update_to_config(self,meta_upgrade,pkgs_install,pkgs_upgrade,pkgs_remove):
+ try:
+ output_upgrade = {}
- output_upgrade.update({"upgrade_groups":now_upgrade.upgrade_groups})
- output_upgrade.update({"single_pkgs":now_upgrade.single_pkgs})
- output_upgrade.update({"pkgs_install":pkgs_install})
- output_upgrade.update({"pkgs_upgrade":pkgs_upgrade})
- output_upgrade.update({"pkgs_remove":pkgs_remove})
+ output_upgrade.update({"push_groups":meta_upgrade.upgrade_groups})
+ output_upgrade.update({"push_pkgs":meta_upgrade.single_pkgs})
+ output_upgrade.update({"pkgs_install":pkgs_install})
+ output_upgrade.update({"pkgs_upgrade":pkgs_upgrade})
+ output_upgrade.update({"pkgs_remove":pkgs_remove})
+ #6 产生JSON文件
+ with open(self.INSTALL_OUTPUT_JSON, 'w', encoding='utf-8') as f:
+ json.dump(output_upgrade, f, ensure_ascii=False, indent=4)
- #6 产生JSON文件
- with open(self.INSTALL_OUTPUT_JSON, 'w', encoding='utf-8') as f:
- json.dump(output_upgrade, f, ensure_ascii=False, indent=4)
-
- logging.info("Generate Jsonfile(%s) to complete... ",self.INSTALL_OUTPUT_JSON)
- logging.info("Update Packages list to config file in shutdown model...")
+ logging.info("Generate Jsonfile(%s) to complete... ",self.INSTALL_OUTPUT_JSON)
+ logging.info("Update Packages list to config file...")
+ except Exception as exc:
+ logging.error(exc)
def _config_to_upgrade(self):
#读取组JSON文件
@@ -908,87 +963,15 @@ class InstallBackend():
try:
data = json.load(f)
- upgrade_groups = data["upgrade_groups"]
- single_pkgs = data["single_pkgs"]
+ upgrade_groups = data["push_groups"]
+ single_pkgs = data["push_pkgs"]
pkgs_install = data["pkgs_install"]
pkgs_upgrade = data["pkgs_upgrade"]
pkgs_remove = data["pkgs_remove"]
except Exception as exc:
logging.error(exc)
- return NowUpgradeMeta(self,upgrade_groups,single_pkgs),pkgs_install,pkgs_upgrade,pkgs_remove
-
- #将安装完成的插入数据库 安装失败的计算那些包安装失败了 分类插入数据库中
- #将安装失败的数据进行返回
- def _make_insert_info(self,success,is_cancelled,_now_upgrade,error_string,error_desc):
- false_num = 0
- #目前去掉打印 错误日志
- # error_desc = error_desc +'\n\n'+self.aptd_base.error_details
- #在安装失败 and 不是取消升级 则走下面的 否则不计算全部直接插入数据库
- if success == False and is_cancelled == False and self.action_mode != self.MODE_INSTALL_SYSTEM:
- #获取当前系统中最新的cache
- fresh_cache = Cache(rootdir=self.window_main.cache.rootdir)
- #获取调整包列表 去掉版本号
- adjust_pkgs = [i.split("=")[0] for i in self.upgrade_data.adjust_pkgs]
-
- #升级存在单包更新 失败后计算每一个包是否安装完成 相应判断进行插入
- for pkg in _now_upgrade.single_pkgs:
- pkg_obj = fresh_cache[pkg]
-
- #判断是否是源过滤调整的包 调整的话 判断安装版本 来解决是否安装成功
- if pkg in adjust_pkgs:
- if pkg_obj._pkg.inst_state == apt_pkg.INSTSTATE_OK and pkg_obj._pkg.current_state == apt_pkg.CURSTATE_INSTALLED and pkg_obj.name + '=' + pkg_obj.installed.source_version in self.upgrade_data.adjust_pkgs:
- self.window_main.sqlite3_server.insert_info(self.action_mode,[pkg],[],self.upgrade_data.adjust_pkgs,True,'', '')
- else:
- false_num += 1
- logging.warning("This single-package(%s) is not install or upgrade",pkg)
- self.window_main.sqlite3_server.insert_info(self.action_mode,[pkg],[],self.upgrade_data.adjust_pkgs,False,error_string, error_desc)
- else:
- #非调整版本的计算方式
- if pkg_obj._pkg.inst_state == apt_pkg.INSTSTATE_OK and pkg_obj._pkg.current_state == apt_pkg.CURSTATE_INSTALLED and pkg_obj.is_now_broken == False:
- self.window_main.sqlite3_server.insert_info(self.action_mode,[pkg],[],self.upgrade_data.adjust_pkgs,True,'', '')
- else:
- false_num += 1
- logging.warning("This single-package(%s) is not install or upgrade",pkg)
- self.window_main.sqlite3_server.insert_info(self.action_mode,[pkg],[],self.upgrade_data.adjust_pkgs,False,error_string, error_desc)
-
- #组的计算是否升级成功的方式 将组按照单包来计算的
- if _now_upgrade.upgrade_groups != []:
- pkgs_install,pkgs_upgrade = self._make_pkgs_list(self.cache,self.upgrade_data.groups_pkgs,_now_upgrade.upgrade_groups,[])
- install_error_pkgs = []
- total_pkg = pkgs_install + pkgs_upgrade
-
- for pkg in total_pkg[::-1]:
- pkg_obj = fresh_cache[pkg]
- if pkg in adjust_pkgs:
- if pkg_obj.is_installed == True and pkg_obj.is_now_broken == False and pkg_obj.installed.source_version + pkg_obj.name in self.upgrade_data.adjust_pkgs:
- total_pkg.remove(pkg)
- else:
- install_error_pkgs.append(pkg)
- else:
- if pkg_obj._pkg.inst_state == apt_pkg.INSTSTATE_OK and pkg_obj._pkg.current_state == apt_pkg.CURSTATE_INSTALLED and pkg_obj.is_now_broken == False:
- total_pkg.remove(pkg)
- else:
- install_error_pkgs.append(pkg)
-
- # group_error_log = '\n'+ "This groups-package"+str(install_error_pkgs)+" is not install or upgrade" + '\n'
- # logging.warning(group_error_log)
- #如果没有
- if total_pkg == []:
- self.window_main.sqlite3_server.insert_info(self.action_mode,[],_now_upgrade.upgrade_groups,self.upgrade_data.adjust_pkgs,True,'', '')
- else:
- false_num += 1
- self.window_main.sqlite3_server.insert_info(self.action_mode,[],_now_upgrade.upgrade_groups,self.upgrade_data.adjust_pkgs,False,error_string,error_desc)
- #关闭临时cache
- fresh_cache.close()
- #其他情况直接写入数据库 不进行计算
- else:
- #取消的话全部是失败
- if is_cancelled == True:
- false_num = len(_now_upgrade.single_pkgs) + len(_now_upgrade.upgrade_groups)
- self.window_main.sqlite3_server.insert_info(self.action_mode,_now_upgrade.single_pkgs,_now_upgrade.upgrade_groups,self.upgrade_data.adjust_pkgs,success,error_string, error_desc)
-
- return false_num
+ return NowUpgradeMeta(_upgrade_groups=upgrade_groups,_single_pkgs=single_pkgs),pkgs_install,pkgs_upgrade,pkgs_remove
def emulate_calcul_broken(self,pkgs):
args = ["apt-get", "install","--simulate"]
@@ -1096,7 +1079,7 @@ class InhibitShutdownLock():
self.pidfile = None
#安装时禁止关机 进行加锁
- def lock(self, caller='Kylin System Updater'):
+ def lock(self, caller='kylin-system-updater'):
"""
Send a dbus signal to logind to not suspend the system, it will be
released when the return value drops out of scope
@@ -1109,8 +1092,8 @@ class InhibitShutdownLock():
'org.freedesktop.login1', '/org/freedesktop/login1',
'org.freedesktop.login1.Manager', 'Inhibit',
GLib.Variant('(ssss)',
- ('shutdown',
- caller, 'Installing Packages',
+ ('shutdown:sleep',
+ caller, _("Installing or removing software packages."),
'block')),
None, 0, -1, None, None)
self.inhibit_lock = Gio.UnixInputStream(fd=fdlist.steal_fds()[var[0]])
@@ -1239,5 +1222,5 @@ class UpdateSafeManager():
logging.info("Set kysec_xattr_set_func_status %s...",str(value))
return True
except Exception as e:
- logging.error("Set kylin Sec Failed and fun:%d value:%d Error msg:" + str(e),fun,value)
+ logging.warning("Set kylin Sec Failed and fun:%d value:%d Error msg:" + str(e),fun,value)
return False
diff --git a/backend/data/cn.kylinos.KylinSystemUpdater.policy b/backend/data/cn.kylinos.KylinSystemUpdater.policy
index 64c3262..90ef97b 100644
--- a/backend/data/cn.kylinos.KylinSystemUpdater.policy
+++ b/backend/data/cn.kylinos.KylinSystemUpdater.policy
@@ -8,9 +8,10 @@
www.kylinos.cn
kylin-system-updater
-
+
+
<_description>
- system level settings
+ Configuration items added for Kirin Installer
<_message>
To Change the settings, you need to authenticate.
@@ -22,4 +23,47 @@
+
+ <_description>
+ Configuration items added for Kirin Uninstaller
+
+ <_message>
+ To Change the settings, you need to authenticate.
+
+
+ auth_admin_keep
+ auth_admin_keep
+ auth_admin_keep
+
+
+
+
+
+ <_description>
+ Configuration items added for Kirin Installer
+
+ <_message>
+ To Change the settings, you need to authenticate.
+
+
+ auth_admin_keep
+ auth_admin_keep
+ auth_admin_keep
+
+
+
+
+
+ <_description>
+ Configuration items added for Kylin Software Center
+
+ <_message>
+ To Change the settings, you need to authenticate.
+
+
+ auth_admin
+ auth_admin
+ auth_admin
+
+
diff --git a/backend/data/com.kylin.UpgradeStrategies.service b/backend/data/com.kylin.UpgradeStrategies.service
index 4b70a1d..7d913e8 100644
--- a/backend/data/com.kylin.UpgradeStrategies.service
+++ b/backend/data/com.kylin.UpgradeStrategies.service
@@ -1,4 +1,4 @@
[D-BUS Service]
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
\ No newline at end of file
diff --git a/backend/data/kylin-system-updater.db b/backend/data/kylin-system-updater.db
index 26e9d40..934a075 100644
Binary files a/backend/data/kylin-system-updater.db and b/backend/data/kylin-system-updater.db differ
diff --git a/backend/data/system-updater-defaults.conf b/backend/data/system-updater-defaults.conf
index a540b41..608cd66 100644
--- a/backend/data/system-updater-defaults.conf
+++ b/backend/data/system-updater-defaults.conf
@@ -1,5 +1,6 @@
[SystemStatus]
abnormal_reboot = False
+reboot_update = False
upload_upgrade_log = True
upload_installer_log = False
diff --git a/backend/data/unattended-upgrades-policy.conf b/backend/data/unattended-upgrades-policy.conf
index 6e92a5a..fe828d7 100644
--- a/backend/data/unattended-upgrades-policy.conf
+++ b/backend/data/unattended-upgrades-policy.conf
@@ -6,7 +6,7 @@ autoUpgradeState = off
preDownload = off
# 预下载的时间为时间段 例如:10:00-11:00
-preDownloadTime = 10:00
+preDownloadTime = 00:00-06:00
#添加检查更新的周期 以天为单位
updateDays = 1
@@ -15,13 +15,16 @@ updateDays = 1
downloadMode = timing
# 下载的时间为时间段 例如:10:00-11:00
-downloadTime = 10:00
+downloadTime = 00:00-05:00
#安装存在定时timing 手动:manual 关机安装bshutdown
-installMode = timing
+installMode = timing
#安装也为时间段 例如:00:00
-installTime = 10:00
+installTime = 05:30-06:00
+
+#立即更新随机波动范围(单位:分钟)
+randomRange = 60
#是否开启自动重启 以及自动重启时间可以调节
automaticReboot = off
diff --git a/backend/data/unattended-upgrades-timestamp b/backend/data/unattended-upgrades-timestamp
index 573541a..578507f 100644
--- a/backend/data/unattended-upgrades-timestamp
+++ b/backend/data/unattended-upgrades-timestamp
@@ -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
diff --git a/backend/kylin-system-updater b/backend/kylin-system-updater
index 2fe08b5..93f614f 100755
--- a/backend/kylin-system-updater
+++ b/backend/kylin-system-updater
@@ -83,7 +83,7 @@ if __name__ == "__main__":
signal.signal(signal.SIGINT,signal_handler_term)
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:
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)
- #当出现安装过程中异常的重启时 开机直接进行修复操作
- # 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:
+ app.configs_uncover.setValue("SystemStatus","abnormal_reboot",str(False),True)
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()
\ No newline at end of file
diff --git a/backend/po/bo_CN.po b/backend/po/bo_CN.po
new file mode 100644
index 0000000..23ee577
--- /dev/null
+++ b/backend/po/bo_CN.po
@@ -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 , 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 \n"
+"Language-Team: LANGUAGE \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 "འཁོར་སྐྱོད་ཞིབ་བཤེར་གྱི་རྐང་པར་རྒྱུན་ལྡན་མིན་པ་བྱུང་།"
\ No newline at end of file
diff --git a/backend/po/zh_CN.po b/backend/po/zh_CN.po
index 6a2e677..3458214 100644
--- a/backend/po/zh_CN.po
+++ b/backend/po/zh_CN.po
@@ -2563,9 +2563,12 @@ msgstr ""
msgid "%.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 "无法访问源管理服务器,请稍后再试"
+msgid "Access to the source management server timed out, please try again later"
+msgstr "访问源管理服务器超时,请稍后再试"
+
msgid "Check if your network requires authentication?"
msgstr "检查您的网络需要认证吗?"
@@ -2760,4 +2763,13 @@ msgid "Please check the system time and synchronize the system time before updat
msgstr "请检查系统时间,同步系统时间后再进行更新。"
msgid "The package is unsigned, refuses to install."
-msgstr "软件包未签名,拒绝安装。"
\ No newline at end of file
+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 "正在安装或删除软件包。"
\ No newline at end of file
diff --git a/backend/po/zh_HK.po b/backend/po/zh_HK.po
index 8aaec3e..a087c21 100644
--- a/backend/po/zh_HK.po
+++ b/backend/po/zh_HK.po
@@ -2525,7 +2525,7 @@ msgstr "因 grub 已安裝,移除 lilo (詳情見 bug #314004)"
#~ msgstr "提取檔案及安裝升級可能要花數小時。一旦下載完成即不能取消升級程序。"
-msgid "Unable to access the source management server"
+msgid "Unable to access the source management server, please try again later"
msgstr "無法存取來源管理伺服器,請稍後再試"
msgid "Check if your network requires authentication?"
diff --git a/backend/po/zh_TW.po b/backend/po/zh_TW.po
index c69880b..f2f6a37 100644
--- a/backend/po/zh_TW.po
+++ b/backend/po/zh_TW.po
@@ -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 "無法存取來源管理伺服器,請稍後再試"
msgid "Check if your network requires authentication?"
diff --git a/backend/report-updater-bug b/backend/report-updater-bug
index 6fa4452..9505777 100755
--- a/backend/report-updater-bug
+++ b/backend/report-updater-bug
@@ -26,6 +26,8 @@ cp -r /var/log/apt/history.log updaterlog || true
#收集aptdamon的日志
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"
diff --git a/debian/changelog b/debian/changelog
index 5c80594..151c1b7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+kylin-system-updater (2.0.5.15-ok4) yangtze; urgency=medium
+
+ * BUG: #无
+ * 需求号: 无
+ * 其他改动说明: 同步2303主线代码
+ * 其他改动影响域:系统更新
+
+ -- Kevin Duan Mon, 29 May 2023 14:47:14 +0800
+
kylin-system-updater (2.0.5.15-ok3) yangtze; urgency=medium
* BUG: #无
diff --git a/unattended-upgrades/kylin-unattended-upgrade b/unattended-upgrades/kylin-unattended-upgrade
index fbeeef1..2e445e1 100644
--- a/unattended-upgrades/kylin-unattended-upgrade
+++ b/unattended-upgrades/kylin-unattended-upgrade
@@ -45,7 +45,7 @@ import grp
import io
import locale
import logging
-import logging.handlers
+
import re
import os
import select
@@ -108,14 +108,16 @@ HTTPTYPE = "HTTP"
FTPTYPE = "FTP"
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="/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)
# from OriginFilter import UnattendUpgradeFilter
+KYLIN_VERSION_FILE = "/etc/kylin-version/kylin-system-version.conf"
CONFIG_FILE_ROOT_PATH="/var/lib/unattended-upgrades"
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"
TIMESTAMP_PATH="/var/lib/kylin-software-properties/template/kylin-source-status"
CONTROL_PANEL_LOCK_FILE = "/tmp/auto-upgrade/ukui-control-center.lock"
@@ -152,77 +154,16 @@ pidfile = None
# set from the sigint signal handler
SIGNAL_STOP_REQUEST = False
-class PackageComponent():
- def MarkUpgrade(self):
- pass
-
- def MarkInstall(self):
- pass
-
-
-class PackageGroup(PackageComponent):
- def __init__(self,name) -> None:
- self.name = name
- self.upgrade_list = []
- self.install_list = []
+def kysec_pre_upgrade():
+ if os.path.exists("/usr/share/kysec-maintain/sys-upgrade-pre.sh"):
+ logging.debug("kysec pre-upgrade settings...")
+ subprocess.run(["/bin/sh","/usr/share/kysec-maintain/sys-upgrade-pre.sh"])
- 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 kysec_post_upgrade():
+ 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"])
+
def reload_options_config():
#添加默认保留旧配置
apt_pkg.config["DPkg::Options::"] = "--force-confold"
@@ -243,7 +184,6 @@ def reload_options_config():
apt_pkg.config["Dir::Etc::sourceparts"]=""
apt_pkg.init_system()
-
def get_default_version():
version = ""
data = {'version':""}
@@ -259,7 +199,7 @@ def get_default_version():
return version
def ReadOsRelease(file):
- osreleasedict={}
+ osreleasedict = {}
try:
with open(file) as f:
lines = f.readlines()
@@ -268,11 +208,13 @@ def ReadOsRelease(file):
osreleasedict.update({ls[0]:ls[1].strip('"')})
except Exception as e:
pass
+ if 'PROJECT_CODENAME' not in osreleasedict.keys():
+ osreleasedict.update({'PROJECT_CODENAME':''})
if 'SUB_PROJECT_CODENAME' not in osreleasedict.keys():
osreleasedict.update({'SUB_PROJECT_CODENAME':''})
return osreleasedict
-
+'''
#安装时禁止关机 进行加锁
def LockedPreventShutdown():
global pidfile
@@ -331,6 +273,7 @@ def unLockedEnableShutdown():
pidfile.close()
pidfile = None
return False
+'''
def is_dpkg_journal_dirty():
# type: () -> bool
@@ -363,6 +306,7 @@ def get_white_list_with_version(srclist,list,namelist):
def get_timestamp():
global timeStamp
config=configparser.ConfigParser(allow_no_value=True)
+ config.optionxform = str
config.read(TIMESTAMP_PATH)
time_value=time.localtime(int(config.get("Server","UpdateTime")))
logging.debug(("获取软件源时间戳:%s"),time_value)
@@ -372,6 +316,7 @@ def get_timestamp():
def WriteValueToFile(file,section,option,value):
config=configparser.ConfigParser(allow_no_value=True)
+ config.optionxform = str
config.add_section(section)
config.set(section,option,value)
config.write(open(file,"w"))
@@ -400,6 +345,7 @@ logged_msgs = set() # type: AbstractSet[str]
NEVER_PIN = -32768
+
class InhibitShutdownLock():
def __init__(self):
@@ -717,34 +663,6 @@ class OriginProperty():
self.allow_origin['ftp'].append(lo)
except Exception as 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):
resultList = []
@@ -850,7 +768,6 @@ class KylinSystemUpdater:
def ConnectToSignals(self):
def update_detect_finished_handler(success,updatelist,error_status,error_cause):
- logging.debug(updatelist)
if success:
logging.info("update detect success,quiting main loop")
self.update_group = updatelist
@@ -872,11 +789,6 @@ class KylinSystemUpdater:
PackageGroup.AddPackageToInstallList(Package(key,data['install_list'][key]['new_version']))
# install_list.append((key,data['install_list'][key]['new_version']))
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():
if key in ["total_download_size","total_install_size"]:
@@ -887,7 +799,7 @@ class KylinSystemUpdater:
if key in ["total_download_size","total_install_size"]:
pass
else:
- self.whitelist_with_candidate_version.append((key,data['install_list'][key]['new_version']))
+ self.whitelist_with_candidate_version.append((key,data['install_list'][key]['new_version']))
'''
if os.path.exists(UNATTENDED_UPGRADE_PKG_LIST_FILE_PATH):
with open(UNATTENDED_UPGRADE_PKG_LIST_FILE_PATH, "r") as f:
@@ -1020,6 +932,7 @@ class KylinBackupManager:
def ReadValueFromFile(file,section,option):
config=configparser.ConfigParser(allow_no_value=True)
+ config.optionxform = str
try:
config.read(file)
value = config[section][option]
@@ -1031,15 +944,19 @@ def Backup():
# do backup
kylin_backup_manager = KylinBackupManager()
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]:
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()
+
if result == 0 and status_code == 99:
pass
else:
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()
ts = get_timestamp()
kylin_backup_manager.ConnectToSignals()
@@ -1050,6 +967,7 @@ def 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.RunMainloop()
+ return True
'''
if node_name != timeStamp:
logging.info("need backup")
@@ -1072,11 +990,9 @@ class UnattendedUpgradesCache(apt.Cache):
def __init__(self, rootdir, whitelist_with_version,blacklist):
- self._cached_candidate_pkgnames = set() # type: Set[str]
-
- self.origin_filter = UnattendUpgradeFilter()
-
- self.allowed_origins = self.origin_filter.GetAllowOrigins()
+ # self._cached_candidate_pkgnames = set() # type: Set[str]
+ unattended_upgrade_filter = UnattendUpgradeFilter()
+ self.allowed_origins = unattended_upgrade_filter.GetAllowOrigins()
logging.info(_("Allowed origins are: %s"),
", ".join(self.allowed_origins))
@@ -1275,7 +1191,7 @@ class UnattendedUpgradesCache(apt.Cache):
def adjust_candidate_with_version(self,pkg,version):
for v in pkg.versions:
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
return True
return False
@@ -1791,28 +1707,35 @@ def get_allowed_origins_legacy():
raise
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 = get_allowed_origins_legacy()
- key = "Unattended-Upgrade::Origins-Pattern"
- try:
- for s in apt_pkg.config.value_list(key):
- allowed_origins.append(substitute(s))
- except ValueError:
- logging.error(_("Unable to parse %s." % key))
- raise
-
- #logging.info("allowed origins are:%s"%"\n".join(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 match_whitelist_string(whitelist, origin):
# 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")
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:
+ 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':
pass
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:
# 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)
if not is_in_allowed_origin(pkg.candidate, cache.allowed_origins):
return ("pkg %s is not in an allowed origin" % pkg.name)
- '''
+
if not is_pkg_change_allowed(pkg,
cache.blacklist,
cache.whitelist,
cache.strict_whitelist):
return ("pkg %s is blacklisted or is not whitelisted"
% pkg.name)
- '''
+
# check if the package is unsafe to upgrade unattended
- '''
+
ignore_require_restart = apt_pkg.config.find_b(
"Unattended-Upgrade::IgnoreAppsRequireRestart", False)
upgrade_requires = pkg.candidate.record.get("Upgrade-Requires")
@@ -2167,12 +2099,17 @@ def sanity_problem(cache, desired_pkg):
and upgrade_requires == "app-restart":
return ("pkg %s requires app-restart, it is not safe to "
"upgrade it unattended")
- '''
- # check that the package we want to upgrade is in the change set
- if desired_pkg and desired_pkg not in changes:
- return ("pkg %s to be marked for upgrade/install is not marked "
- "accordingly" % desired_pkg.name)
- return None
+
+ # check that the package we want to upgrade is in the change set
+ 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
+ '''
+ 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):
@@ -2653,37 +2590,38 @@ def _setup_logging(options,logfile):
# 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)
+ # stdout_handler = logging.StreamHandler(sys.stdout)
+ # logger.addHandler(stdout_handler)
elif options.verbose:
logger.setLevel(logging.INFO)
- stdout_handler = logging.StreamHandler(sys.stdout)
- logger.addHandler(stdout_handler)
- # if apt_pkg.config.find("Unattended-Upgrade::Mail", ""):
- # mem_log_handler = logging.StreamHandler(mem_log)
- # logger.addHandler(mem_log_handler)
- # Configure syslog if necessary
- # syslogEnable = apt_pkg.config.find_b("Unattended-Upgrade::SyslogEnable",
- # False)
- # if syslogEnable:
- # syslogFacility = apt_pkg.config.find(
- # "Unattended-Upgrade::SyslogFacility",
- # "daemon")
- # syslogHandler = logging.handlers.SysLogHandler(
- # address='/dev/log',
- # facility=syslogFacility) # type: ignore
- # syslogHandler.setFormatter(
- # logging.Formatter("unattended-upgrade: %(message)s"))
- # known = syslogHandler.facility_names.keys() # type: ignore
- # if syslogFacility.lower() in known:
- # logger.addHandler(syslogHandler)
- # logging.info("Enabled logging to syslog via %s facility "
- # % syslogFacility)
- # else:
- # logging.warning("Syslog facility %s was not found"
- # % syslogFacility)
- # return mem_log
-
+ stdout_handler = logging.StreamHandler(sys.stdout)
+ logger.addHandler(stdout_handler)
+ '''
+ if apt_pkg.config.find("Unattended-Upgrade::Mail", ""):
+ mem_log_handler = logging.StreamHandler(mem_log)
+ logger.addHandler(mem_log_handler)
+ Configure syslog if necessary
+ syslogEnable = apt_pkg.config.find_b("Unattended-Upgrade::SyslogEnable",
+ False)
+ if syslogEnable:
+ syslogFacility = apt_pkg.config.find(
+ "Unattended-Upgrade::SyslogFacility",
+ "daemon")
+ syslogHandler = logging.handlers.SysLogHandler(
+ address='/dev/log',
+ facility=syslogFacility) # type: ignore
+ syslogHandler.setFormatter(
+ logging.Formatter("unattended-upgrade: %(message)s"))
+ known = syslogHandler.facility_names.keys() # type: ignore
+ if syslogFacility.lower() in known:
+ logger.addHandler(syslogHandler)
+ logging.info("Enabled logging to syslog via %s facility "
+ % syslogFacility)
+ else:
+ logging.warning("Syslog facility %s was not found"
+ % syslogFacility)
+ return mem_log
+ '''
def logged_in_users():
# type: () -> AbstractSet[str]
@@ -2694,7 +2632,25 @@ def logged_in_users():
USERS, universal_newlines=True).rstrip('\n')
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():
# type: () -> None
"""auto-reboot (if required and the config for this is set)"""
@@ -2757,7 +2713,7 @@ def try_to_upgrade(pkg, # type: apt.Package
except NoAllowedOriginError:
return
- cache._cached_candidate_pkgnames.add(pkg.name)
+ # cache._cached_candidate_pkgnames.add(pkg.name)
if not pkg.installed:
cache.mark_install_adjusted(pkg,from_user=True)
else:
@@ -2794,9 +2750,27 @@ def calculate_upgradable_pkgs(cache, # type: UnattendedUpgradesCache
for pkgname in whitelist:
try:
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:
logging.error("error checking pkg:%s"%e)
continue
+
+ '''
+ if check_changes_for_sanity(cache, pkg):
+ # add to packages to upgrade
+ pkgs_to_upgrade.append(pkg)
+ '''
#for pkg in cache:
# if pkg.name not in cache.whitelist:
# 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):
logging.debug("Checking: %s (%s)" % (
pkg.name, getattr(pkg.candidate, "origins", [])))
- '''
+
if (pkg.is_upgradable or candidate_version_changed(pkg) or not pkg.is_installed):
try:
ver_in_allowed_origin(pkg, cache.allowed_origins)
@@ -2814,15 +2788,15 @@ def calculate_upgradable_pkgs(cache, # type: UnattendedUpgradesCache
continue
- try_to_upgrade(pkg,
+ try_to_upgrade(pkg,
pkgs_to_upgrade,
cache,pkgname[1])
-
+ '''
# logging.debug("Checking: %s (%s)" % (
# pkg.name, getattr(pkg.candidate, "origins", [])))
#pkgs_to_upgrade.append(pkg)
- if cache.get_changes():
- cache.clear()
+ if cache.get_changes():
+ cache.clear()
return pkgs_to_upgrade
@@ -3074,16 +3048,19 @@ def main(options, rootdir="/"):
# return 1
try:
+ kysec_pre_upgrade()
res = run(options, rootdir, logfile_dpkg)
+ kysec_post_upgrade()
logging.info("result:%s,%s"%(res.success,res.result_str))
release = ''
version = ''
os_release_info = ReadOsRelease('/etc/os-release')
if 'KYLIN_RELEASE_ID' in os_release_info:
release = os_release_info['KYLIN_RELEASE_ID']
+ #version = ReadValueFromFile(VERSION_FILE,'SYSTEM','version')
version = get_default_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 = {}
date = time.strftime("%Y-%m-%d %H:%M:%S")
@@ -3105,18 +3082,20 @@ def main(options, rootdir="/"):
UpdateInfos.update({"status":1})
UpdateInfos.update({"errorCode":"cache commit error"})
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:
# f.write(time.time())
- config=configparser.ConfigParser(allow_no_value=True)
- config.read(KYLIN_VERSION_FILE)
- config.set("SYSTEM","os_version",release)
- config.set("SYSTEM","update_version",version)
- with open(KYLIN_VERSION_FILE,'w') as f:
- config.write(f)
- kylin_system_updater.InsertUpgradeHistory(history)
- json_file = json.dumps(UpdateInfos.copy())
- kylin_system_updater.DataBackendCollect("UpdateInfos",json_file)
+ config=configparser.ConfigParser(allow_no_value=True)
+ config.read(KYLIN_VERSION_FILE)
+ config.set("SYSTEM","os_version",release)
+ config.set("SYSTEM","update_version",version)
+ with open(KYLIN_VERSION_FILE,'w') as f:
+ config.write(f)
+ # kylin_system_updater.SetConfigValue("SYSTEM","os_version",release)
+ # kylin_system_updater.SetConfigValue("SYSTEM","update_version",original_version)
+ kylin_system_updater.InsertUpgradeHistory(history)
+ json_file = json.dumps(UpdateInfos.copy())
+ kylin_system_updater.DataBackendCollect("UpdateInfos",json_file)
elif not res.success:
errorlist = kylin_system_updater.DumpInstallErrorRecord()
errorlist.append("cache commit error")
@@ -3133,35 +3112,35 @@ def main(options, rootdir="/"):
else:
logging.info("no pkgs to install")
-
- if 'PROJECT_CODENAME' in os_release_info:
- if os_release_info['PROJECT_CODENAME']=='V10SP1-edu':
- if 'SUB_PROJECT_CODENAME' in os_release_info:
- if os_release_info['SUB_PROJECT_CODENAME']=='mavis':
- 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.add_section("OTA")
- config_to_result.set("OTA","time",localtime)
- config_to_result.set("OTA","version","1.0")
- config_to_result.set("OTA","upgrade","0")
- config_to_result.set("OTA","status","failed")
- if res.success:
- if options.mode == 'shutdown':
- config_to_result.set("OTA","status","success")
- if len(res.pkgs) > 0 :
- config_to_result.set("OTA","upgrade","1")
- if not os.path.exists(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)
- if not os.path.exists(OTA_RESULT_FILE):
- f = open(OTA_RESULT_FILE,'w')
- f.close()
- with open(OTA_RESULT_FILE,"w+") as f:
- config_to_result.write(f)
- 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_IRWXU|stat.S_IRWXG|stat.S_IRWXO)
-
+
+ if 'PROJECT_CODENAME' in os_release_info:
+ if os_release_info['PROJECT_CODENAME']=='V10SP1-edu':
+ if 'SUB_PROJECT_CODENAME' in os_release_info:
+ if os_release_info['SUB_PROJECT_CODENAME']=='mavis':
+ 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.add_section("OTA")
+ config_to_result.set("OTA","time",localtime)
+ config_to_result.set("OTA","version","1.0")
+ config_to_result.set("OTA","upgrade","0")
+ config_to_result.set("OTA","status","failed")
+ if res.success:
+ if options.mode == 'shutdown':
+ config_to_result.set("OTA","status","success")
+ if len(res.pkgs) > 0 :
+ config_to_result.set("OTA","upgrade","1")
+ if not os.path.exists(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)
+ if not os.path.exists(OTA_RESULT_FILE):
+ f = open(OTA_RESULT_FILE,'w')
+ f.close()
+ with open(OTA_RESULT_FILE,"w+") as f:
+ config_to_result.write(f)
+ 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_IRWXU|stat.S_IRWXG|stat.S_IRWXO)
+
# WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle")
'''
@@ -3197,6 +3176,8 @@ def main(options, rootdir="/"):
except Exception as e:
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle")
logging.error(e)
+ if options.install_only:
+ reboot_if_needed()
# logger = logging.getLogger()
# logger.exception(_("An error occurred: %s"), e)
# log_content = get_dpkg_log_content(logfile_dpkg,
@@ -3376,7 +3357,7 @@ def run(options, # type: Options
False, _("Apt returned an error, exiting"))
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"))
return UnattendedUpgradesResult(
False, _("Cache has broken packages, exiting"))
@@ -3394,17 +3375,20 @@ def run(options, # type: Options
pass
else:
raise
- '''
+ '''
#auto_removable = get_auto_removable(cache)
# find out about the packages that are upgradable (in an allowed_origin)
pkgs_to_upgrade = calculate_upgradable_pkgs(cache, options,white_list_with_version)
+ if options.install_only or options.download_and_install:
+ if (len(pkgs_to_upgrade)0:
logging.warning("there're pkgs to download")
try:
@@ -3494,8 +3479,15 @@ def run(options, # type: Options
if os_release_info['SUB_PROJECT_CODENAME']=='mavis':
pass
else:
- logging.info("neeed backup")
- #Backup()
+ logging.info("need backup")
+ backup_result = False
+ backup_result = Backup()
+ if (backup_result):
+ pass
+ else:
+ logging.debug("backup failed...")
+ return UnattendedUpgradesResult(False,"backup failed")
+
# do install
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","install")
#send install start msg to notify
@@ -3517,11 +3509,13 @@ def run(options, # type: Options
% (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()
@@ -3575,7 +3569,7 @@ def run(options, # type: Options
break
#fetcher_statistics.ResetFetcher(fetcher)
#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 os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
docker_image_fetch_result = 0
@@ -3605,12 +3599,87 @@ def run(options, # type: Options
except SystemError:
logging.error(_("lock release failed"))
return UnattendedUpgradesResult(True,_("all pkgs downloaded"))
- else:
+ elif fetcher_statistics.incomplete_pkg_amount > 0 and len(pkgs_to_upgrade) > 0:
try:
apt_pkg.pkgsystem_unlock()
except SystemError:
logging.error(_("lock release failed"))
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:
try:
apt_pkg.pkgsystem_unlock()
@@ -3910,12 +3979,14 @@ class Options:
def __init__(self):
self.download_only = False
self.install_only = False
+ self.download_and_install = False
self.dry_run = False
self.debug = False
self.apt_debug = False
self.verbose = False
self.minimal_upgrade_steps = False
self.mode = None
+
shutdown_lock = -1
@@ -3969,7 +4040,10 @@ if __name__ == "__main__":
help=_("Only download, do not even try to install."))
parser.add_option("", "--install-only",
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",
action="store_true", default=minimal_steps_default,
help=_("Upgrade in minimal steps (and allow "
@@ -4027,13 +4101,27 @@ if __name__ == "__main__":
pass
# 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
os_release_info = ReadOsRelease('/etc/os-release')
#print(os_release_info)
config_manager = ConfigFileManager(CONFIG_FILE_ROOT_PATH)
login_manager = LoginManager()
kylin_system_updater = KylinSystemUpdater()
+
'''
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
pass
@@ -4065,6 +4153,9 @@ if __name__ == "__main__":
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","download")
elif options.install_only:
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
install_start_time = datetime.datetime.now().replace(microsecond=0)
logging.info("unattended-upgrades start time:%s"%install_start_time)
diff --git a/unattended-upgrades/kylin-unattended-upgrade-shutdown b/unattended-upgrades/kylin-unattended-upgrade-shutdown
index 8a4ce3e..e36189e 100644
--- a/unattended-upgrades/kylin-unattended-upgrade-shutdown
+++ b/unattended-upgrades/kylin-unattended-upgrade-shutdown
@@ -26,20 +26,22 @@
#
import copy
+# from multiprocessing.connection import wait
+# from concurrent.futures import ThreadPoolExecutor
+# from stat import filemode
import dbus
import signal
import sys
import time
import datetime
import logging
-import logging.handlers
+
import gettext
import subprocess
import os.path
import os
import configparser
import psutil
-from pytz import timezone
# for dbus signal handling
try:
from dbus.mainloop.glib import DBusGMainLoop
@@ -49,10 +51,10 @@ except ImportError:
from optparse import OptionParser, Values
Values # pyflakes
-from gettext import gettext as _
+from gettext import gettext as _, install
from threading import Event
from enum import IntEnum, Enum
-from apscheduler.schedulers.blocking import BlockingScheduler
+from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.schedulers.background import BackgroundScheduler
import random
import threading
@@ -85,7 +87,6 @@ AUTO_UPGRADE_POLICY_OPTION_UPGRADE_INTERVAL = "upgradeInverval"
INTERVAL_DOWN_INSTALL = 120 # 下载安装的间隔 分钟
INSTALL_RANDOM = 5 # 安装时间随机数范围0-INSTALL_RANDOM 分钟
DOWNLOAD_RANDOM = 180 # 下载时间随机数范围0-DOWNLOAD_RANDOM 分钟
-PREDOWNLOAD_RANDOM = 180
class FeatureSwitch(Enum):
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",\
"/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():
#添加默认保留旧配置
apt_pkg.config["DPkg::Options::"] = "--force-confold"
@@ -178,6 +233,8 @@ def ReadOsRelease(file):
osreleasedict.update({ls[0]:ls[1].strip('"')})
except Exception as e:
pass
+ if 'PROJECT_CODENAME' not in osreleasedict.keys():
+ osreleasedict.update({'PROJECT_CODENAME':''})
if 'SUB_PROJECT_CODENAME' not in osreleasedict.keys():
osreleasedict.update({'SUB_PROJECT_CODENAME':''})
return osreleasedict
@@ -196,6 +253,7 @@ def FindRuningUnattendedUpgrades():
def ReadValueFromFile(file,section,option):
config=configparser.ConfigParser(allow_no_value=True)
+ config.optionxform = str
try:
config.read(file)
value = config[section][option]
@@ -205,6 +263,7 @@ def ReadValueFromFile(file,section,option):
def WriteValueToFile(file,section,option,value):
config=configparser.ConfigParser(allow_no_value=True)
+ config.optionxform = str
config.add_section(section)
config.set(section,option,value)
config.write(open(file,"w"))
@@ -217,68 +276,6 @@ def clean_flag_files(filelist):
def init():
if not os.path.exists(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):
# type: (str) -> None
@@ -391,7 +388,110 @@ class TimerThread(threading.Thread):
self.scheduler = scheduler
def run(self):
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:
def __init__(self) -> None:
DBusGMainLoop(set_as_default=True)
@@ -405,7 +505,8 @@ class KylinSystemUpdater:
def SetConfigValue(self,section,option,value):
return self.update_interface.SetConfigValue(section,option,value)
-
+
+
class AutoUpgradePolicy():
def __init__(self) -> None:
self.autoupgradepolicy = {}
@@ -425,33 +526,77 @@ class AutoUpgradePolicy():
try:
return self.autoupgradepolicy[option]
except Exception:
- return ''
-
- def reload_config(self):
- if os.path.exists(UNATTENDED_UPGRADE_POLICY_FILE_PATH):
- config=configparser.ConfigParser(allow_no_value=True)
- config.optionxform = str
- config.read(UNATTENDED_UPGRADE_POLICY_FILE_PATH)
- for option in config.options('autoUpgradePolicy'):
- self.autoupgradepolicy.update({option:config['autoUpgradePolicy'][option]})
- for key in self.autoupgradepolicy.keys():
- logging.debug("%s:%s"%(key,self.autoupgradepolicy[key]))
-
+ return ''
+
+ def ExecutePolicy(self,property,value):
+ if property == 'autoUpgradeState':
+ if value == 'off':
+ background_scheduler.pause_job('download')
+ background_scheduler.pause_job('install')
+ elif value == 'on':
+ if self.autoupgradepolicy['downloadMode'] == 'timing':
+ background_scheduler.resume_job('download')
+ 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():
# 加载配置文件 unattended-upgrades-policy.conf
- '''
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.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.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)
- # self.download_random = int(kylin_system_updater.GetConfigValue('AutoUpgradeConfig','downloadRandom')[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))
+ self.download_random = int(kylin_system_updater.GetConfigValue('AutoUpgradeConfig','downloadRandom')[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))
# 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':
self.download_time['h'] = 10
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_mode, self.install_mode)
return
-
+ '''
timelist = download_time.strip().split(':')
-
if len(timelist) != TimeElement.TIME_NUM:
logging.debug("unattended-upgrades-policy.conf time err %s",download_time)
return
-
# 检查 传入时间 安全性
try:
tmphour = int(timelist[TimeElement.TIME_HOUR])
@@ -490,8 +633,7 @@ class UnattendedUpgradesShutdown():
self.preDownload, self.autoUpgrade, self.download_mode, self.install_mode)
else:
logging.debug("unattended-upgrades-policy.conf not exist")
- return
- '''
+
def __init__(self, options):
# type: (Values) -> None
self.options = options
@@ -518,8 +660,9 @@ class UnattendedUpgradesShutdown():
self.download_job = None
self.install_job = None
self.startup_download_job = None
- self.scheduler = BlockingScheduler(timezone = "Asia/Shanghai")
+ self.scheduler = BlockingScheduler()
'''
+
try:
hasattr(GLib, "MainLoop")
DBusGMainLoop(set_as_default=True)
@@ -534,15 +677,26 @@ class UnattendedUpgradesShutdown():
self.inhibit_lock = None
self.logind_proxy = None
self.update_proxy = None
+ self.upgrade_strategy_proxy = None
self.wait_period = min(3, self.get_inhibit_max_delay() / 3)
self.preparing_for_shutdown = False
#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):
if not self.update_proxy:
bus = dbus.SystemBus()
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):
self.update_interface = dbus.Interface(self.update_proxy,dbus_interface='com.kylin.systemupgrade.interface')
@@ -593,7 +747,7 @@ class UnattendedUpgradesShutdown():
/ (1000 * 1000))
except dbus.exceptions.DBusException:
return 3
-
+ '''
def is_preparing_for_shutdown(self):
if not self.shutdown_pending:
try:
@@ -606,7 +760,7 @@ class UnattendedUpgradesShutdown():
except dbus.exceptions.DBusException:
return False
return self.shutdown_pending
-
+ '''
def start_iterations(self):
while self.iter():
time.sleep(1)
@@ -644,7 +798,7 @@ class UnattendedUpgradesShutdown():
while not self.iter():
# TODO iter on sigterm and sighup, too
time.sleep(self.wait_period)
- '''
+
# 定时下载 执行函数
def timing_download(self):
env = copy.copy(os.environ)
@@ -659,7 +813,7 @@ class UnattendedUpgradesShutdown():
def timing_install(self):
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)
+ timing_install_ret = subprocess.run(["kylin-unattended-upgrade","--install-only"], env=env)
if timing_install_ret.returncode == 0:
logging.debug("kylin-unattended-upgrade install success.")
else:
@@ -679,7 +833,7 @@ class UnattendedUpgradesShutdown():
logging.info("wait for uu time out")
return
return 0
-
+
def _pause_timer(self):
if self.download_job is not None:
self.download_job.pause()
@@ -693,7 +847,7 @@ class UnattendedUpgradesShutdown():
if self.install_job is not None:
self.install_job.resume()
-
+ '''
def run(self):
""" 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':
@@ -713,7 +867,7 @@ class UnattendedUpgradesShutdown():
"only if it is running")
self.stop_signal_received.set()
#self.start_iterations()
-
+ '''
# fall back to polling without GLib
try:
hasattr(GLib, "MainLoop")
@@ -721,41 +875,22 @@ class UnattendedUpgradesShutdown():
logging.error("MainLoop Not Found")
#self.run_polling(signal_handler)
return
-
+ '''
for sig in (signal.SIGTERM, signal.SIGHUP):
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, sig,
signal_handler, None, None)
'''
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():
- if os.path.exists(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))
- '''
+ if os.path.isfile(UNATTENDED_UPGRADE_POLICY_FILE_PATH):
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.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]",
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)
- '''
+
else:
logging.debug("unattended-upgrades-policy.conf not exist")
-
+ '''
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()
- '''
+ 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():
logging.warning("find runing unattended-upgrades,please wait")
return False
else:
- self._pause_timer()
+ #self._pause_timer()
env = copy.copy(os.environ)
retdownload = subprocess.run(["kylin-unattended-upgrade","--download-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:
return True
else:
return False
'''
-
def prepare_for_shutdown_handler(active):
""" Handle PrepareForShutdown() """
if not active:
@@ -946,8 +1079,13 @@ class UnattendedUpgradesShutdown():
self.mainloop.quit()
self.get_update_proxy()
self.get_update_interface()
- self.update_proxy.connect_to_signal("ChangeUpgradePolicy",change_upgrade_policy_handler)
- self.update_proxy.connect_to_signal("UpgradeAllNow",upgrade_all_now_handler)
+ self.get_upgrade_strategy_proxy()
+ 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:
self.get_logind_proxy().connect_to_signal(
@@ -967,21 +1105,22 @@ class UnattendedUpgradesShutdown():
logging.debug("Skip waiting for signals, starting operation "
"now")
# self.start_iterations()
- '''
+
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
logging.info("setting startup download timer")
GLib.timeout_add(300*1000, lambda: self.timing_download() and False)
#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:
+ '''
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'])
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'])
elif self.autoUpgrade == FeatureSwitch.OFF.value:
logging.info("auto upgrade turned off")
- '''
+ '''
+ pass
#TimerThread(self.scheduler).start()
self.mainloop.run()
logging.info("quit mainloop")
@@ -1017,9 +1156,11 @@ class UnattendedUpgradesShutdown():
env = copy.copy(os.environ)
#env["UNATTENDED_UPGRADES_FORCE_INSTALL_ON_SHUTDOWN"] = "1"
logging.info("starting unattended-upgrades in shutdown mode")
+ '''
if FindRuningUnattendedUpgrades():
logging.warning("another unattended-upgrade is running , quit")
return False
+ '''
self.on_shutdown_mode_uu_proc = subprocess.Popen(
["kylin-unattended-upgrade","--install-only","--mode=shutdown"], env=env)
#log_msg(_("Running unattended-upgrades in shutdown mode"))
@@ -1178,18 +1319,37 @@ if __name__ == "__main__":
if not os.path.exists(logdir):
os.makedirs(logdir)
logfile = os.path.join(logdir, "unattended-upgrades-shutdown.log")
- logging.basicConfig(filename=logfile,
- level=level,
- format="%(asctime)s %(levelname)s - %(message)s")
- logging.getLogger('apscheduler').setLevel(logging.DEBUG)
+ #_setup_logging(options,logfile)
+ # logging.basicConfig(filename=logfile,
+ # level=level,
+ # 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')
logging.info("project id:%s,sub-project id:%s"%(os_release_info['PROJECT_CODENAME'],os_release_info['SUB_PROJECT_CODENAME']))
-
+ '''
time_stamp = "0"
if os.path.exists(TIME_STAMP):
with open(TIME_STAMP,'r') as f:
time_stamp = f.readline()
logging.info("time stamp:%s"%time_stamp)
+ '''
# setup gettext
localesApp = "unattended-upgrades"
localesDir = "/usr/share/locale"
@@ -1214,6 +1374,7 @@ if __name__ == "__main__":
signal.signal(signal.SIGTERM, signal_term_handler)
signal.signal(signal.SIGHUP, signal.SIG_IGN)
dpkg_fix=None
+ '''
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
dpkg_journal_dirty = is_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))
if abnormal_pkg_count != '0':
apt_fix = subprocess.run("echo y|apt install -f",shell=True,stdout=open(logfile,'a+'),stderr=open(logfile,'a+'))
+ '''
kylin_system_updater = KylinSystemUpdater()
autoupgradepolicy = AutoUpgradePolicy()
- background_scheduler = BackgroundScheduler(timezone = "Asia/Shanghai")
+ background_scheduler = BackgroundScheduler()
background_scheduler_init(background_scheduler)
+ #executor = ThreadPoolExecutor(max_workers=1)
UnattendedUpgradesShutdown(options).run()
#main()