diff -Nru kylin-system-updater-3.0.0.0/debian/changelog kylin-system-updater-3.0.0.0/debian/changelog
--- kylin-system-updater-3.0.0.0/debian/changelog	2024-11-27 13:56:00.000000000 +0800
+++ kylin-system-updater-3.0.0.0/debian/changelog	2025-02-25 14:13:19.000000000 +0800
@@ -1,3 +1,21 @@
+kylin-system-updater (3.0.0.0-ok34) nile; urgency=medium
+
+  * BUG: 无
+  * 需求号: 无
+  * 其他改动说明: 修复编译报错
+  * 其他改动影响域:无
+
+ -- wangsong <wangsong@kylinos.cn>  Tue, 25 Feb 2025 14:13:19 +0800
+
+kylin-system-updater (3.0.0.0-ok33) nile; urgency=medium
+
+  * BUG: 无
+  * 需求号: 无
+  * 其他改动说明: 同步主线V11改动
+  * 其他改动影响域:无
+
+ -- wangsong <wangsong@kylinos.cn>  Thu, 13 Feb 2025 10:04:42 +0800
+
 kylin-system-updater (3.0.0.0-ok32) nile; urgency=medium
 
   * BUG: 
diff -Nru kylin-system-updater-3.0.0.0/debian/kylin-system-updater-immutable.install kylin-system-updater-3.0.0.0/debian/kylin-system-updater-immutable.install
--- kylin-system-updater-3.0.0.0/debian/kylin-system-updater-immutable.install	2024-11-27 13:56:00.000000000 +0800
+++ kylin-system-updater-3.0.0.0/debian/kylin-system-updater-immutable.install	2025-02-25 14:13:19.000000000 +0800
@@ -1,30 +1,33 @@
 #!/usr/bin/dh-exec
-#backend
-backend-immutable/data/kylin-system-updater.db /usr/share/kylin-system-updater/
-backend-immutable/report-updater-bug /usr/bin
-backend-immutable/data/30kylin-system-updater /etc/apt/apt.conf.d/
+
+# dbus服务配置
 backend-immutable/data/com.kylin.systemupgrade.conf /etc/dbus-1/system.d/
-#backend-immutable/data/com.kylin.systemupgrade.limit /etc/dbus-1/conf/
 backend-immutable/data/kylin-system-updater.service /usr/lib/systemd/system/
-#backend-immutable/data/kylin-upgrade-poweroff.service /usr/lib/systemd/system/
-backend-immutable/data/kylin-logout-required /usr/share/kylin-system-updater/
-backend-immutable/data/kylin-reboot-required /usr/share/kylin-system-updater/
+backend-immutable/data/cn.kylinos.KylinSystemUpdater.policy  /usr/share/polkit-1/actions/
+
+# 配置文件安装
+backend-immutable/data/settings-default.json /etc/kylin-system-updater/
+
+# 程序代码安装
 backend-immutable/kylin-system-updater /usr/share/kylin-system-updater/
-backend-immutable/monitor-reboot /usr/share/kylin-system-updater/
 backend-immutable/SystemUpdater/*.py /usr/share/kylin-system-updater/SystemUpdater/
 backend-immutable/SystemUpdater/backend/*.py /usr/share/kylin-system-updater/SystemUpdater/backend/
 backend-immutable/SystemUpdater/Core/*.py /usr/share/kylin-system-updater/SystemUpdater/Core/
+backend-immutable/SystemUpdater/packageManager/*.py /usr/share/kylin-system-updater/SystemUpdater/packageManager/
 backend-immutable/build/mo/* /usr/share/locale/
+backend-immutable/report-updater-bug /usr/bin
 
-backend-immutable/data/system-updater-defaults.conf /etc/kylin-system-updater/
+# 自动更新配置安装
 backend-immutable/data/unattended-upgrades-policy.conf /var/lib/unattended-upgrades/
 backend-immutable/data/unattended-upgrades-timestamp /var/lib/unattended-upgrades/
-backend-immutable/data/cn.kylinos.KylinSystemUpdater.policy  /usr/share/polkit-1/actions/
+
+# 版本配置文件
 backend-immutable/data/kylin-system-version.conf /etc/kylin-version/
+backend-immutable/data/kylin-system-updater.db /usr/share/kylin-system-updater/
 
 #configDaemon
 backend-immutable/kylin-upgrade-strategies /usr/share/kylin-system-updater/
 backend-immutable/data/com.kylin.UpgradeStrategies.conf /etc/dbus-1/system.d/
 backend-immutable/data/com.kylin.UpgradeStrategies.service /usr/share/dbus-1/system-services/
 backend-immutable/data/cn.kylinos.UpgradeStrategies.policy  /usr/share/polkit-1/actions/
-backend-immutable/data/kylin-system-updater /etc/logrotate.d
+backend-immutable/data/kylin-system-updater /etc/logrotate.d
\ No newline at end of file
diff -Nru kylin-system-updater-3.0.0.0/debian/patches/0026-changelog-3.0.0.0-ok33.patch kylin-system-updater-3.0.0.0/debian/patches/0026-changelog-3.0.0.0-ok33.patch
--- kylin-system-updater-3.0.0.0/debian/patches/0026-changelog-3.0.0.0-ok33.patch	1970-01-01 08:00:00.000000000 +0800
+++ kylin-system-updater-3.0.0.0/debian/patches/0026-changelog-3.0.0.0-ok33.patch	2025-02-25 14:13:19.000000000 +0800
@@ -0,0 +1,17031 @@
+From: wangsong <wangsong@kylinos.cn>
+Date: Thu, 13 Feb 2025 10:05:10 +0800
+Subject: changelog:3.0.0.0-ok33
+
+---
+ .../SystemUpdater/Core/DataAcquisition.py          |   50 +-
+ backend-immutable/SystemUpdater/Core/Database.py   |   34 +-
+ .../SystemUpdater/Core/DbusControl.py              |   87 +
+ .../SystemUpdater/Core/PluginManager.py            |  397 ---
+ backend-immutable/SystemUpdater/Core/UpdateList.py |    8 +-
+ .../SystemUpdater/Core/diskManager.py              |  123 +
+ backend-immutable/SystemUpdater/Core/enums.py      |   96 +-
+ .../SystemUpdater/Core/quitStrategiesService.py    |   60 +
+ .../SystemUpdater/Core/space_rules.py              |  175 ++
+ backend-immutable/SystemUpdater/UpdateManager.py   |  132 +-
+ .../SystemUpdater/UpdateManagerDbus.py             |  225 +-
+ .../SystemUpdater/UpdatesAvailable.py              |  129 +-
+ .../SystemUpdater/UpgradeStrategies.py             |   39 +-
+ .../SystemUpdater/UpgradeStrategiesDbus.py         |  268 +-
+ .../SystemUpdater/backend/BackendOstreeNext.py     |  292 +-
+ backend-immutable/SystemUpdater/configs.py         |   67 +
+ backend-immutable/SystemUpdater/constants.py       |   12 +
+ .../packageManager/UpdaterSDKInterface.py          |  584 ++++
+ .../SystemUpdater/packageManager/__init__.py       |    0
+ .../SystemUpdater/packageManager/pmEnums.py        |  370 +++
+ .../SystemUpdater/packageManager/pmUtils.py        |  932 +++++++
+ .../SystemUpdater/packageManager/pmWorker.py       |  201 ++
+ backend-immutable/SystemUpdater/pluginbase.py      |  449 ++++
+ .../SystemUpdater/plugins/update/randomstr.py      |   11 +
+ backend-immutable/SystemUpdater/push_update.py     |   83 +
+ .../data/com.kylin.UpgradeStrategies.limit         |   33 +
+ .../data/com.kylin.UpgradeStrategies.limit.verify  |    1 +
+ backend-immutable/data/settings-default.json       |    3 +
+ backend-immutable/kylin-system-updater             |   13 +-
+ backend-immutable/kylin-upgrade-strategies         |    2 +-
+ backend-immutable/po/bo_CN.po                      |    4 +
+ backend-immutable/po/zh_CN.po                      |   17 +-
+ backend-immutable/po/zh_HK.po                      |    4 +
+ backend-immutable/po/zh_TW.po                      |    4 +
+ .../data/cn.kylinos.KylinSystemUpdater.policy      |  129 +
+ .../tests/data/cn.kylinos.UpgradeStrategies.policy |   25 +
+ .../tests/data/com.kylin.UpgradeStrategies.conf    |   23 +
+ .../tests/data/com.kylin.UpgradeStrategies.limit   |   33 +
+ .../data/com.kylin.UpgradeStrategies.limit.verify  |    1 +
+ .../tests/data/com.kylin.UpgradeStrategies.service |    4 +
+ .../tests/data/com.kylin.systemupgrade.conf        |   23 +
+ .../tests/data/com.kylin.systemupgrade.limit       |   14 +
+ backend-immutable/tests/data/inhibit-sleep.conf    |   25 +
+ backend-immutable/tests/data/kylin-system-updater  |   10 +
+ .../tests/data/kylin-system-updater.db             |  Bin 0 -> 40960 bytes
+ .../tests/data/kylin-system-updater.service        |   13 +
+ .../tests/data/kylin-system-version.conf           |    3 +
+ backend-immutable/tests/data/settings-default.json |    3 +
+ .../tests/data/unattended-upgrades-policy.conf     |   44 +
+ .../tests/data/unattended-upgrades-timestamp       |    4 +
+ backend-immutable/tests/diskManager_unittest.py    |   30 +
+ backend-immutable/tests/enums.sh                   |   12 +-
+ backend-immutable/tests/interface.md               |  657 +++++
+ backend-immutable/tests/kylin-system-updater       |   80 +
+ backend-immutable/tests/kylin-upgrade-strategies   |   81 +
+ backend-immutable/tests/libtest-core.sh            |   33 -
+ backend-immutable/tests/libtest.sh                 |  144 +-
+ backend-immutable/tests/po/ChangeLog               |    6 +
+ backend-immutable/tests/po/Makefile                |   28 +
+ backend-immutable/tests/po/POTFILES.in             |    9 +
+ backend-immutable/tests/po/POTFILES.skip           |    0
+ backend-immutable/tests/po/bo_CN.po                |  242 ++
+ backend-immutable/tests/po/zh_CN.po                | 2821 ++++++++++++++++++++
+ backend-immutable/tests/po/zh_HK.po                | 2712 +++++++++++++++++++
+ backend-immutable/tests/po/zh_TW.po                | 2744 +++++++++++++++++++
+ backend-immutable/tests/report-updater-bug         |   62 +
+ backend-immutable/tests/setup.cfg                  |   15 +
+ backend-immutable/tests/setup.py                   |   21 +
+ backend-immutable/tests/sqlite_tests.py            |   13 +
+ backend-immutable/tests/test-configs.py            |   86 +
+ backend-immutable/tests/test-for-frontend.sh       |   45 +
+ backend-immutable/tests/test-offline-upgrade.sh    |  202 ++
+ backend-immutable/tests/test-pull.sh               |   39 +
+ backend-immutable/tests/test-push-update.sh        |  201 ++
+ backend-immutable/tests/test-upgrade-endoflife.sh  |   54 +
+ 75 files changed, 14820 insertions(+), 776 deletions(-)
+ create mode 100644 backend-immutable/SystemUpdater/Core/DbusControl.py
+ create mode 100644 backend-immutable/SystemUpdater/Core/diskManager.py
+ create mode 100755 backend-immutable/SystemUpdater/Core/quitStrategiesService.py
+ create mode 100644 backend-immutable/SystemUpdater/Core/space_rules.py
+ create mode 100644 backend-immutable/SystemUpdater/configs.py
+ create mode 100644 backend-immutable/SystemUpdater/constants.py
+ create mode 100644 backend-immutable/SystemUpdater/packageManager/UpdaterSDKInterface.py
+ create mode 100644 backend-immutable/SystemUpdater/packageManager/__init__.py
+ create mode 100644 backend-immutable/SystemUpdater/packageManager/pmEnums.py
+ create mode 100644 backend-immutable/SystemUpdater/packageManager/pmUtils.py
+ create mode 100644 backend-immutable/SystemUpdater/packageManager/pmWorker.py
+ create mode 100644 backend-immutable/SystemUpdater/pluginbase.py
+ create mode 100644 backend-immutable/SystemUpdater/plugins/update/randomstr.py
+ create mode 100644 backend-immutable/SystemUpdater/push_update.py
+ create mode 100644 backend-immutable/data/com.kylin.UpgradeStrategies.limit
+ create mode 100644 backend-immutable/data/com.kylin.UpgradeStrategies.limit.verify
+ create mode 100644 backend-immutable/data/settings-default.json
+ create mode 100644 backend-immutable/tests/data/cn.kylinos.KylinSystemUpdater.policy
+ create mode 100644 backend-immutable/tests/data/cn.kylinos.UpgradeStrategies.policy
+ create mode 100644 backend-immutable/tests/data/com.kylin.UpgradeStrategies.conf
+ create mode 100644 backend-immutable/tests/data/com.kylin.UpgradeStrategies.limit
+ create mode 100644 backend-immutable/tests/data/com.kylin.UpgradeStrategies.limit.verify
+ create mode 100644 backend-immutable/tests/data/com.kylin.UpgradeStrategies.service
+ create mode 100644 backend-immutable/tests/data/com.kylin.systemupgrade.conf
+ create mode 100644 backend-immutable/tests/data/com.kylin.systemupgrade.limit
+ create mode 100644 backend-immutable/tests/data/inhibit-sleep.conf
+ create mode 100644 backend-immutable/tests/data/kylin-system-updater
+ create mode 100644 backend-immutable/tests/data/kylin-system-updater.db
+ create mode 100644 backend-immutable/tests/data/kylin-system-updater.service
+ create mode 100644 backend-immutable/tests/data/kylin-system-version.conf
+ create mode 100644 backend-immutable/tests/data/settings-default.json
+ create mode 100644 backend-immutable/tests/data/unattended-upgrades-policy.conf
+ create mode 100644 backend-immutable/tests/data/unattended-upgrades-timestamp
+ create mode 100644 backend-immutable/tests/diskManager_unittest.py
+ create mode 100644 backend-immutable/tests/interface.md
+ create mode 100755 backend-immutable/tests/kylin-system-updater
+ create mode 100755 backend-immutable/tests/kylin-upgrade-strategies
+ create mode 100644 backend-immutable/tests/po/ChangeLog
+ create mode 100644 backend-immutable/tests/po/Makefile
+ create mode 100644 backend-immutable/tests/po/POTFILES.in
+ create mode 100644 backend-immutable/tests/po/POTFILES.skip
+ create mode 100644 backend-immutable/tests/po/bo_CN.po
+ create mode 100644 backend-immutable/tests/po/zh_CN.po
+ create mode 100644 backend-immutable/tests/po/zh_HK.po
+ create mode 100644 backend-immutable/tests/po/zh_TW.po
+ create mode 100755 backend-immutable/tests/report-updater-bug
+ create mode 100644 backend-immutable/tests/setup.cfg
+ create mode 100755 backend-immutable/tests/setup.py
+ create mode 100644 backend-immutable/tests/sqlite_tests.py
+ create mode 100644 backend-immutable/tests/test-configs.py
+ create mode 100755 backend-immutable/tests/test-for-frontend.sh
+ create mode 100755 backend-immutable/tests/test-offline-upgrade.sh
+ create mode 100755 backend-immutable/tests/test-pull.sh
+ create mode 100755 backend-immutable/tests/test-push-update.sh
+ create mode 100755 backend-immutable/tests/test-upgrade-endoflife.sh
+
+diff --git a/backend-immutable/SystemUpdater/Core/DataAcquisition.py b/backend-immutable/SystemUpdater/Core/DataAcquisition.py
+index ab6fe09..32fa611 100644
+--- a/backend-immutable/SystemUpdater/Core/DataAcquisition.py
++++ b/backend-immutable/SystemUpdater/Core/DataAcquisition.py
+@@ -13,13 +13,13 @@ import shutil
+ import hashlib
+ import logging
+ import tarfile
+-import requests
++import datetime
+ import threading
+ 
+-from datetime import datetime,timezone,timedelta
++from datetime import datetime
+ from binascii import a2b_hex
+ from urllib import parse, request
+-from SystemUpdater.Core import enums
++from SystemUpdater.packageManager.pmEnums import *
+ from json.decoder import JSONDecodeError
+ from dbus.exceptions import DBusException
+ from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
+@@ -72,7 +72,15 @@ class UpdateMsgCollector():
+         MODE_INSTALL_PARTIAL:"upgrade_partial"
+     }
+     action_map = {
+-
++        ACTION_CHECK_RESOLVER:MONIT_DEPRESOLUT,
++        ACTION_INSTALL:MONIT_INSTALL,
++        ACTION_INSTALL_DEB:MONIT_INSTALLDEB,
++        10:MONIT_FINISH,
++        "finish-updatedetect":MONIT_DETECT,
++        "finish-download":MONIT_DOWNLOAD,
++        "finish-downfinish":MONIT_DOWNLOAD,
++        "finish-update":MONIT_FINISH,
++        "finish-install":MONIT_FINISH
+     }
+     messageType_map = {
+         "finish-updatedetect":"UpdateDetect",
+@@ -660,13 +668,13 @@ class PHPServer(threading.Thread):
+                 gZipFile(log_dir, log_file_gzip)
+                 header = {'Content-Type': "multipart/form-data", "Accept-Encoding": "gzip"}
+                 try:
++                    import requests
++
+                     with open(log_file_gzip, "rb") as f:
+                         requests.post(self.PINGBACK_INTRANET_FILE_URL + "filename=" + os.path.basename(log_file_gzip),
+                                       data=f.read(), headers=header, timeout = (3,3))
+-                except:
+-                    with open(log_file_gzip, "rb") as f:
+-                        requests.post(self.PINGBACK_INTERNET_FILE_URL + "filename=" + os.path.basename(log_file_gzip),
+-                                      data=f.read(), headers=header, timeout = (3,3))
++                except Exception as e:
++                    logging.error("The external log server error: %s .", e)
+             else:
+                 log_file_gzip = ""
+             kmg_tmp = {'ip': host_ip, 'version': version, 'soft_version': soft_version, 'datetime': nowtime,
+@@ -700,15 +708,25 @@ def gZipFile(src, dst):
+       tar.add(src, arcname=os.path.basename(src))
+ 
+ def get_east_8_time():
+-    now_time = ""
+-
+-    try:
+-        now_time = datetime.now(timezone.utc) + timedelta(hours=8)
+-        now_time = now_time.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
+-    except:
+-        pass
+-
++    import time
++    # UTC时间
++    utc_time = datetime.utcnow() 
++    # 转时间字符串
++    utc_time = utc_time.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
++    time_suffix = utc_time.split(".")[1]
++    # 字符串转时间元祖
++    utc_time = time.strptime(utc_time, "%Y-%m-%d %H:%M:%S.%f")
++    # 时间元祖转时间戳
++    utc_time = time.mktime(utc_time)
++    # 生成东八区时间时间戳
++    now_time = utc_time + 8*60*60
++    # 时间戳转时间元祖
++    now_time = time.localtime(now_time)
++    # 时间元祖转字符串
++    now_time = time.strftime("%Y-%m-%d %H:%M:%S",now_time)
++    now_time = now_time + "." +time_suffix
+     return now_time
++    # return 0
+ 
+ def GetActivationCode():
+     Code = ''
+diff --git a/backend-immutable/SystemUpdater/Core/Database.py b/backend-immutable/SystemUpdater/Core/Database.py
+index 82a35d2..4b17082 100644
+--- a/backend-immutable/SystemUpdater/Core/Database.py
++++ b/backend-immutable/SystemUpdater/Core/Database.py
+@@ -26,7 +26,7 @@ INSTALLED_LIST = [{"item": "errorcode", "type": "int", "default": "0"}]
+ DISPALY_LIST = []
+ 
+ class Sqlite3Server(object):
+-    def __init__(self, updateManager, _no_DataMigration=False):
++    def __init__(self, updateManager=None, _no_DataMigration=False):
+         self.connect = None
+         self.window_main = updateManager
+         self.init_sqlit()
+@@ -60,6 +60,10 @@ class Sqlite3Server(object):
+         self.deb_metadata.update({"new_version":''})
+         self.deb_metadata.update({"old_update_version":''})
+         self.deb_metadata.update({"new_update_version":''})
++        self.deb_policy_timestamp = 0
++        self.deb_policy_keep = False
++        self.purge_policy_timestamp = 0
++        self.purge_policy_keep = False
+ 
+     # Initialize the connection database and modify it to connect when using
+     def init_sqlit(self):
+@@ -146,10 +150,24 @@ class Sqlite3Server(object):
+ 
+     # 写入数据到display表中
+     def insert_into_display(self, *args, **kwargs):
++        display_filed_lists = ["check_time","update_time","auto_check","system_version","auto_backup","download_limit",
++                                "download_limit_value","allow_unattended_upgrades_shutdown","update_period",
++                                "firstmigration","autoupdate_allow","tid","init_version"]
++        if args[0] not in display_filed_lists:
++            return "Error"
++
++        def is_valid_string(s):
++            pattern = r'^[a-zA-Z0-9=:_\-\s]+$'
++            return bool(re.fullmatch(pattern, s))
++
++        if not is_valid_string(args[1]):
++            logging.error("Invalid args: %s", args[1])
++            return "Error"
++
+         self.connect_database()
+         try:
+-            sql = "update display set " + args[0] + "='" + args[1] + "' where id = 1"
+-            self.cursor.execute(sql)
++            sql = f"update display set {args[0]} = ? where id = 1"
++            self.cursor.execute(sql, (str(args[1]), ))
+             self.connect.commit()
+         except Exception as e:
+             logging.error("Insert error: %s.", str(e))
+@@ -274,12 +292,7 @@ class Sqlite3Server(object):
+         try:
+             output_config_name = '/var/cache/kylin-system-updater/json/kylin-update-desktop-system.json'
+ 
+-            if success:
+-                status = 'success'
+-                status_cn = '成功'
+-            else:
+-                status = 'failed'
+-                status_cn = '失败'
++            status, status_cn = ('success', '成功')  if success else ('failed', '失败')
+ 
+             try:
+                 with open(output_config_name,'r') as f:
+@@ -303,6 +316,9 @@ class Sqlite3Server(object):
+ 
+             errstr = get_error_description_from_enum(error_code)
+ 
++            if not success and not errstr:
++                errstr = _('System upgrade error')
++
+             self.insert_into_updateinfo(pkgappname, pkgversion, pkgdescription, pkgtimestr, \
+                                         pkgstatus, pkgkeyword, errstr, pkgappnamecn, pkgstatuscn, pkgchangelog)
+ 
+diff --git a/backend-immutable/SystemUpdater/Core/DbusControl.py b/backend-immutable/SystemUpdater/Core/DbusControl.py
+new file mode 100644
+index 0000000..f7c7e3c
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/Core/DbusControl.py
+@@ -0,0 +1,87 @@
++#!/usr/bin/python3
++
++import os
++import configparser
++import logging
++import dbus
++from gettext import gettext as _
++
++from SystemUpdater.Core.errors import *
++from SystemUpdater.Core.enums import *
++
++class DbusControl():
++    def __init__(self,dbus,debug):
++        self.dbus = dbus
++        self.debug = debug
++        self.prohibit_env = ["LD_PRELOAD","LD_LIBRARY_PATH","LD_AUDIT"]
++        self.config = configparser.ConfigParser()
++        self.whitelist_values = []
++        try:
++            self.config.read("/etc/dbus-1/conf/com.kylin.UpgradeStrategies.limit")
++            whitelist = self.config['whitelist']
++            for key in whitelist:
++                self.whitelist_values.append(whitelist[key])
++        except Exception as e:
++            logging.warning("Skip dbus control and dsc:%s",str(e))
++
++    def _get_environment_from_pid(self, pid):
++        try:
++            with open(f'/proc/{pid}/environ', 'r') as f:
++                environ = f.read()
++            # 环境变量用 '\0' 分隔,替换为换行符便于读取
++            env_vars = environ.split('\0')
++            env_dict = {var.split('=')[0]: var.split('=')[1] for var in env_vars if '=' in var}
++            return env_dict
++        except Exception as e:
++            logging.error("Error reading environment variables: %s",str(e))
++            return None
++
++    def _get_process_path_from_pid(self, pid):
++        try:
++            # 读取 /proc/[pid]/exe 符号链接获取进程路径
++            process_path = os.readlink(f'/proc/{pid}/exe')
++            if process_path.startswith('/usr/bin/python'):
++                cmd_file = '/proc/%u/cmdline' % pid
++                with open(cmd_file, 'r') as cf:
++                    cmd_line = cf.readline()
++                    cmds = cmd_line.split('\0')
++                    if len(cmds) >= 2:
++                        process_path = cmds[1]
++            return process_path
++        except Exception as e:
++            return str(e)
++
++    def _get_pid_from_dbus_name(self,dbus_name, bus=None):
++        """Return a deferred that gets the id of process owning the given
++        system D-Bus name.
++        """
++        bus_obj = self.dbus.get_object("org.freedesktop.DBus",
++                                "/org/freedesktop/DBus/Bus")
++        pid = bus_obj.GetConnectionUnixProcessID(dbus_name,
++                                        dbus_interface="org.freedesktop.DBus")
++        # proc = psutil.Process(int(pid))
++
++        return int(pid)
++
++    def check_sender(self,sender,skip_check=False):
++        pid = self._get_pid_from_dbus_name(sender)
++
++        process_path = self._get_process_path_from_pid(pid)
++
++        if self.debug or skip_check:
++            return process_path
++
++        # 检查运行白名单
++        if self.whitelist_values and process_path not in self.whitelist_values:
++            logging.error("dbus method control,operation not permitted. sender:%s",process_path)
++            raise dbus.exceptions.DBusException("dbus method control,operation not permitted.")
++
++        # # 检查环境变量
++        # env_vars = self._get_environment_from_pid(pid)
++
++        # if env_vars:
++        #     for env in self.prohibit_env:
++        #         if env in env_vars:
++        #             logging.error("dbus method control,env forbidden. sender:%s env:%s",process_path,env)
++        #             raise dbus.exceptions.DBusException("dbus method control,env forbidden.")
++        return process_path
+\ No newline at end of file
+diff --git a/backend-immutable/SystemUpdater/Core/PluginManager.py b/backend-immutable/SystemUpdater/Core/PluginManager.py
+index 19eda71..752c5dd 100644
+--- a/backend-immutable/SystemUpdater/Core/PluginManager.py
++++ b/backend-immutable/SystemUpdater/Core/PluginManager.py
+@@ -1,402 +1,5 @@
+ #!/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-immutable/SystemUpdater/Core/UpdateList.py b/backend-immutable/SystemUpdater/Core/UpdateList.py
+index b0213fd..e8f7e85 100644
+--- a/backend-immutable/SystemUpdater/Core/UpdateList.py
++++ b/backend-immutable/SystemUpdater/Core/UpdateList.py
+@@ -1,17 +1,17 @@
+ # UpdateList.py
+ 
+-from gettext import gettext as _
++
+ import logging
+ import os
+ import json
+ import yaml
+-from gi.repository import Gio
+ from .errors import *
+ from .enums import *
++from gi.repository import Gio
++from gettext import gettext as _
++from SystemUpdater.constants import OUTPUT_JSON_PATH
+ 
+ class UpdateList():
+-    OUTPUT_JSON_PATH = '/var/lib/kylin-system-updater/json/'
+-
+     def __init__(self,parent):
+         self.parent = parent
+         self.uuconfigs = self.parent.uuconfigs
+diff --git a/backend-immutable/SystemUpdater/Core/diskManager.py b/backend-immutable/SystemUpdater/Core/diskManager.py
+new file mode 100644
+index 0000000..5e71509
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/Core/diskManager.py
+@@ -0,0 +1,123 @@
++import os
++import logging
++import apt_pkg
++from gettext import gettext as _
++from SystemUpdater.Core.errors import *
++from SystemUpdater.Core.enums import *
++
++class diskManager():
++    def __init__(self) -> None:
++        self.mounted_list = None
++        self.mounted_point_free_space = None
++        self.init_finish = False
++        self._start()
++
++    def _start(self):
++        try:
++            self.mounted_list = self._get_mount_points()
++            self.mounted_point_free_space = self._get_mounted_point_free_space()
++            self.init_finish = True
++        except Exception as e:
++            logging.error(e)
++
++    def _get_mount_points(self):
++        # 获得系统的挂载点列表
++        # get the mount points list from /proc/mounts
++        mounted = []
++        with open("/proc/mounts") as mounts:
++                for line in mounts:
++                    try:
++                        (what, where, fs, options, a, b) = line.split()
++                    except ValueError as e:
++                        logging.debug("line '%s' in /proc/mounts not understood (%s)" % (line, e))
++                        continue
++                    if not where in mounted:
++                        mounted.append(where)
++            # make sure mounted is sorted by longest path
++        mounted.sort(key=len, reverse=True)
++        return mounted
++    
++    def _get_mounted_point_free_space(self):
++        # 获取系统每个挂载点的剩余空间
++        fs_free = {}
++        for mount_point in self.mounted_list:
++            statvfs = os.statvfs(mount_point)
++            free = statvfs.f_frsize * statvfs.f_bavail # 剩余空间,单位 GB
++            fs_free[mount_point] = free
++        return fs_free
++    
++    def _get_mounted_point_by_dir(self, archivedir):
++        """ return 'id' of a directory so that directories on the
++            same filesystem get the same id (simply the mount_point)
++        """
++        for mount_point in self.mounted_list:
++            if archivedir.startswith(mount_point):
++                return mount_point
++        return "/"
++
++    # External interface
++    def check_space_size_by_size(self, download_size, additional_size):
++        '''
++        download_size: 下载包的总大小
++        additional_size: 除下载空间外还需要额外的空间大小
++        通过输入的需求安装列表,计算挂载点大小
++        安装下载的地址通过 archivedir = apt_pkg.config.find_dir("Dir::Cache::archives") 自动获取
++        '''
++        if self.init_finish is True:
++            result = True
++            install_req_size = {}
++            notfree_mounted_pointed = []
++            try:
++                # 下载路径
++                archivedir = apt_pkg.config.find_dir("Dir::Cache::archives")
++                # V11上使用ostree,安装路径为/ostree/repo
++                # 除安装空间外还预留一些安全空间缓冲区,设置为固定值
++                for (dir, size) in [(archivedir, download_size),
++                                            # 需要检测/ostree下是否足够安装,安装空间需求=下载大小+额外需要空间
++                                            ("/ostree", download_size + additional_size),
++                                            ("/", 500*1024*1024),     # small safety buffer /
++                                            ]:
++                    mounted_point = self._get_mounted_point_by_dir(dir)
++                    if size < 0:
++                        # 兼容出现负数的BUG
++                        continue
++                    if mounted_point in install_req_size:
++                        install_req_size[mounted_point] += size
++                    else:
++
++                        install_req_size[mounted_point] = size
++                    logging.debug(f"dir {dir} needs {size} disk size")
++                
++                for mounted_point in install_req_size:
++                    if self.mounted_point_free_space[mounted_point] > install_req_size[mounted_point]:
++                        continue
++                    else:
++                        result = False
++                        notfree_mounted_pointed.append(mounted_point)
++
++                if result is False:
++                    logging.error(f"Not enough free space:{notfree_mounted_pointed}")
++                else:
++                    logging.info("Check: Enough free space For system update...")
++            except Exception as e:
++                logging.error(e)
++                result = False
++
++        else:
++            result = False
++            logging.error("diskManager Initialization is not complete")
++            return result
++
++        return result
++    
++def check_free_space(download_size, addition_size=0):
++    try:
++        _diskManager = diskManager()
++        result =_diskManager.check_space_size_by_size(download_size, addition_size)
++        if result is False:
++            raise UpdateBaseError(ERROR_NOT_DISK_SPACE)
++    except Exception as e:
++        logging.error(e)
++        raise UpdateBaseError(ERROR_NOT_DISK_SPACE)
++        return False
++    return True
+\ No newline at end of file
+diff --git a/backend-immutable/SystemUpdater/Core/enums.py b/backend-immutable/SystemUpdater/Core/enums.py
+index 2b7aeaa..602943f 100644
+--- a/backend-immutable/SystemUpdater/Core/enums.py
++++ b/backend-immutable/SystemUpdater/Core/enums.py
+@@ -2,19 +2,32 @@
+ # -*- coding: utf-8 -*-
+ """enums - Enumerates for apt daemon dbus messages"""
+ 
+-__all__ = (
+-            #错误枚举
+-            "ERROR_OTHER_PROGRESS_OCCUPATION","ERROR_NETWORK_FAILED","ERROR_CANCELLED","ERROR_NOT_ROLLBAK_DEPLOYMENT",
+-            "ERROR_ORIGIN_IS_NONE","INSTALL_FAILED_FALG","INSTALL_SUCCESS_FLAG","INSTALL_DEFAULT_FLAG",
+-            # 方法
+-            "get_error_description_from_enum"
+-        )
++# __all__ = (
++#             #错误枚举
++#             "ERROR_OTHER_PROGRESS_OCCUPATION","ERROR_NETWORK_FAILED","EXIT_CANCELLED","ERROR_NOT_ROLLBAK_DEPLOYMENT",
++#             "ERROR_ORIGIN_IS_NONE","INSTALL_FAILED_FALG","INSTALL_SUCCESS_FLAG","INSTALL_DEFAULT_FLAG","ERROR_UPDATE_SOURCE_FAILED",
++#             "ERROR_PROGRAM_EXCEPTION","ERROR_NOT_DISK_SPACE","ERROR_PUSH_BRANCH_EXCEPTION","ERROR_REPO_IS_NONE",
++
++#             # 方法
++#             "get_error_description_from_enum","get_error_num_from_enum"
++#         )
+ 
+ import gettext
+ gettext.bindtextdomain('kylin-system-updater', '/usr/share/locale')
+ gettext.textdomain('kylin-system-updater')
+ _ = gettext.gettext
+ 
++
++# 更新事务进行过程中的角色
++ROLE_UNSET = "role-unset"
++# 检查更新
++ROLE_UPDATE_CACHE = "role-update-cache"
++#更新下载
++ROLE_DOWNLOAD_ONLY = "role-download-only"
++# 更新部署
++ROLE_DEPLOY_ONLY = "role-deploy-only"
++
++
+ #系统更新的所有枚举
+ PRIORITY_UPGRADE_SUCCCESSED = "priority-upgrade-successed"
+ INSTALL_DEFAULT_FLAG = 'none'
+@@ -22,24 +35,25 @@ INSTALL_FAILED_FALG = 'failed'
+ INSTALL_SUCCESS_FLAG = 'success'
+ #apt update阶段出现的错误解析
+ 
+-
+-
+-
+-
+ #通用错误
+-ERROR_PROGRAM_EXCEPTION = "#0000"
+-ERROR_OTHER_PROGRESS_OCCUPATION = "#0001"
+-ERROR_NETWORK_FAILED = "#0002"
++ERROR_PROGRAM_EXCEPTION = "error-program-exception"
++ERROR_OTHER_PROGRESS_OCCUPATION = "error-other-progress-occupation"
++ERROR_NETWORK_FAILED = "error-network-failed"
+ 
+-#检查更新错误 1
+-ERROR_ORIGIN_IS_NONE = "#0100"
++#检查更新错误
++ERROR_ORIGIN_IS_NONE = "error-origin-is-none"
++ERROR_REPO_IS_NONE = "error-repo-is-none"
++ERROR_UPDATE_SOURCE_FAILED = "error-update-source-failed"
++ERROR_PUSH_BRANCH_EXCEPTION = "error-push-branch-exception"
+ 
+ 
+-#下载错误 2
+-ERROR_CANCELLED = "#0200"
++#下载错误
++EXIT_CANCELLED = "exit-cancelled"
++ERROR_NOT_DISK_SPACE = "error-not-disk-space"
+ 
+-#部署错误 3
+-ERROR_NOT_ROLLBAK_DEPLOYMENT = "#0300"
++#部署错误
++ERROR_NOT_DEPLOYMENT = "error-not-deployment"
++ERROR_NOT_ROLLBAK_DEPLOYMENT = "error-not-rollback-deployment"
+ 
+ 
+ GLIB_ERROR_NETWORK_FAILED = "While fetching mirrorlist"
+@@ -47,12 +61,50 @@ GLIB_ERROR_NETWORK_FAILED = "While fetching mirrorlist"
+ _DESCS_ERROR = {
+                     ERROR_OTHER_PROGRESS_OCCUPATION: _("Other tasks are being updated and upgraded, please try again later."),
+                     ERROR_NETWORK_FAILED: _("Network anomaly, can't check for updates!"),
+-                    ERROR_CANCELLED: _("_Cancel Upgrade"),
++                    ERROR_REPO_IS_NONE: _("Name of the repository deployed by the current system is empty."),
++
++                    ERROR_UPDATE_SOURCE_FAILED: _("Unable to access the source management server, please try again later"),
++                    EXIT_CANCELLED: _("_Cancel Upgrade"),
+                     ERROR_NOT_ROLLBAK_DEPLOYMENT: _("There is no way to rollback to the previous version, there is nothing to rollback."),
+-                    ERROR_ORIGIN_IS_NONE: _("Check for update exceptions! Please verify that the system deployment is complete.")
++                    ERROR_ORIGIN_IS_NONE: _("Check for update exceptions! Please verify that the system deployment is complete."),
++                    ERROR_NOT_DISK_SPACE: _("Disk space is insufficient, please clean the disk and then upgrade"),
++                    ERROR_PUSH_BRANCH_EXCEPTION: _("Update push is abnormal, and the corresponding branch information cannot be found on the server."),
+ 
++                    # 更新部署错误
++                    ERROR_NOT_DEPLOYMENT: _("The system has not been deployed, please check the system deployment status.")
+                 }
++_CODE_ERROR = {
++    #通用错误码
++    ERROR_PROGRAM_EXCEPTION: "#0000",
++    ERROR_NETWORK_FAILED: "#0001",
++    ERROR_OTHER_PROGRESS_OCCUPATION: "#0002",
++    ERROR_PUSH_BRANCH_EXCEPTION: "#0003",
++    ERROR_REPO_IS_NONE: "#0004",
++
++    #检查更新错误
++    ERROR_UPDATE_SOURCE_FAILED: "#0100",
++    ERROR_ORIGIN_IS_NONE: "#0101",
++
++    #下载错误 2
++    EXIT_CANCELLED: "#0200",
++    ERROR_NOT_DISK_SPACE: "#0201",
++
++    #部署错误 3
++    ERROR_NOT_DEPLOYMENT: "#0300",
++    ERROR_NOT_ROLLBAK_DEPLOYMENT: "#0301"
++}
++
++def get_error_num_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_description_from_enum(enum):
+     """Get a long description of an error.
+ 
+diff --git a/backend-immutable/SystemUpdater/Core/quitStrategiesService.py b/backend-immutable/SystemUpdater/Core/quitStrategiesService.py
+new file mode 100755
+index 0000000..ee5f629
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/Core/quitStrategiesService.py
+@@ -0,0 +1,60 @@
++#!/usr/bin/python3
++
++import dbus
++import psutil
++import signal
++import logging
++
++STRATEGIES_DBUS_PATH = '/com/kylin/UpgradeStrategies'
++STRATEGIES_DBUS_SERVICE = 'com.kylin.UpgradeStrategies'
++STRATEGIES_DBUS_INTERFACE = 'com.kylin.UpgradeStrategies.interface'
++
++process_names = [
++    "kylin-upgrade-strategies",
++    "kconf2 monitor kylin-update-frontend."]
++
++def _quit_strategies_service():
++    try:
++        bus = dbus.SystemBus()
++        the_other_guy = bus.get_object(STRATEGIES_DBUS_SERVICE,
++                                        STRATEGIES_DBUS_PATH)
++        the_other_guy.Quit(dbus_interface=STRATEGIES_DBUS_INTERFACE,
++                            timeout=2)
++    except Exception as e:
++        pass
++
++def kill_process_tree(pid, sig=signal.SIGTERM):
++    try:
++        parent = psutil.Process(pid)
++    except psutil.NoSuchProcess:
++        return
++
++    children = parent.children(recursive=True)
++    for child in children:
++        try:
++            child.send_signal(sig)
++        except psutil.NoSuchProcess:
++            pass
++
++    try:
++        parent.send_signal(sig)
++    except psutil.NoSuchProcess:
++        pass
++
++def _quit_force_strategies_service():
++    try:
++        for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
++            if isinstance(proc.info['cmdline'], list):
++                cmdline_str = ' '.join(proc.info['cmdline'])
++
++            if any(name in cmdline_str for name in process_names):
++                print(f"正在终止进程 {cmdline_str} - {proc}")
++                kill_process_tree(proc.info['pid'])
++    except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
++        pass
++    except Exception as e:
++        logging.error("_quit_force_strategies_service err:%s", e)
++
++if __name__ == "__main__":
++    _quit_strategies_service()
++    _quit_force_strategies_service()
+\ No newline at end of file
+diff --git a/backend-immutable/SystemUpdater/Core/space_rules.py b/backend-immutable/SystemUpdater/Core/space_rules.py
+new file mode 100644
+index 0000000..b45fffa
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/Core/space_rules.py
+@@ -0,0 +1,175 @@
++import os
++import re
++import glob
++import locale
++import logging
++import apt_pkg
++from gettext import gettext as _
++from SystemUpdater.Core.errors import *
++from SystemUpdater.Core.enums import *
++# from SystemUpdater.Core.DistUpgradeCache import FreeSpaceRequired
++
++def estimate_kernel_initrd_size_in_boot():
++    """estimate the amount of space used by the kernel and initramfs in /boot,
++    including a safety margin
++    """
++    kernel = 0
++    initrd = 0
++    kver = os.uname()[2]
++    for f in glob.glob("/boot/*%s*" % kver):
++        if f == '/boot/initrd.img-%s' % kver:
++            initrd += os.path.getsize(f)
++        # don't include in the estimate any files that are left behind by
++        # an interrupted package manager run
++        elif (f.find('initrd.img') >= 0 or f.find('.bak') >= 0
++              or f.find('.dpkg-') >= 0):
++            continue
++        else:
++            kernel += os.path.getsize(f)
++    if kernel == 0:
++        # logging.warning(
++        #     "estimate_kernel_initrd_size_in_boot() returned '0' for kernel?")
++        kernel = 16*1024*1024
++    if initrd == 0:
++        # logging.warning(
++        #     "estimate_kernel_initrd_size_in_boot() returned '0' for initrd?")
++        initrd = 100*1024*1024
++    # add small safety buffer
++    kernel += 1*1024*1024
++    # safety buffer as a percentage of the existing initrd's size
++    initrd_buffer = 1*1024*1024
++    if initrd * 0.05 > initrd_buffer:
++        initrd_buffer = initrd * 0.05
++    initrd += initrd_buffer
++    return kernel,initrd
++KERNEL_SIZE, INITRD_SIZE = estimate_kernel_initrd_size_in_boot()
++
++def kernel_spaces_requires(pkgs_list):
++    # now calculate the space that is required on /boot
++    # we do this by checking how many linux-image-$ver packages
++    # are installed or going to be installed
++    kernel_count = 0
++    for pkg_name in pkgs_list:
++        # we match against everything that looks like a kernel
++        # and add space check to filter out metapackages
++        if re.match("^linux-(image|image-debug)-[0-9.]*-.*", pkg_name):
++            # upgrade because early in the release cycle the major version
++            # may be the same or they might be -lts- kernels
++            logging.info("%s (new-install) added with %s to boot space" % (pkg_name, KERNEL_SIZE))
++            kernel_count += 1
++    # space calculated per LP: #1646222
++    kernel_space = (kernel_count * KERNEL_SIZE
++                        + (kernel_count + 1) * INITRD_SIZE)
++    return kernel_space
++
++def check_free_space(required_download=0,additional_required_space=0,kernel_space=0):
++    """
++    this checks if we have enough free space on /var, /boot and /usr
++    with the given cache
++
++    Note: this can not be fully accurate if there are multiple
++            mountpoints for /usr, /var, /boot
++    """
++
++    class FreeSpace(object):
++        " helper class that represents the free space on each mounted fs "
++        def __init__(self, initialFree):
++            self.free = initialFree
++            self.need = 0
++
++    def make_fs_id(d):
++        """ return 'id' of a directory so that directories on the
++            same filesystem get the same id (simply the mount_point)
++        """
++        for mount_point in mounted:
++            if d.startswith(mount_point):
++                return mount_point
++        return "/"
++
++    # this is all a bit complicated
++    # 1) check what is mounted (in mounted)
++    # 2) create FreeSpace objects for the dirs we are interested in
++    #    (mnt_map)
++    # 3) use the  mnt_map to check if we have enough free space and
++    #    if not tell the user how much is missing
++    mounted = []
++    mnt_map = {}
++    fs_free = {}
++    try:
++        with open("/proc/mounts") as mounts:
++            for line in mounts:
++                try:
++                    (what, where, fs, options, a, b) = line.split()
++                except ValueError as e:
++                    logging.debug("line '%s' in /proc/mounts not understood (%s)" % (line, e))
++                    continue
++                if not where in mounted:
++                    mounted.append(where)
++        # make sure mounted is sorted by longest path
++        mounted.sort(key=len, reverse=True)
++
++        archivedir = apt_pkg.config.find_dir("Dir::Cache::archives")
++        for d in ["/", "/usr", "/var", "/boot", archivedir, "/home", "/tmp/"]:
++            d = os.path.realpath(d)
++            fs_id = make_fs_id(d)
++            if os.path.exists(d):
++                st = os.statvfs(d)
++                free = st.f_bavail * st.f_frsize
++            else:
++                logging.warning("directory '%s' does not exists" % d)
++                free = 0
++            if fs_id in mnt_map:
++                logging.debug("Dir %s mounted on %s" %
++                                (d, mnt_map[fs_id]))
++                fs_free[d] = fs_free[mnt_map[fs_id]]
++            else:
++                logging.debug("Free space on %s: %s" %
++                                (d, free))
++                mnt_map[fs_id] = d
++                fs_free[d] = FreeSpace(free)
++        del mnt_map
++
++        # sum up space requirements
++        for (dir, size) in [(archivedir, required_download),
++                            ("/usr", additional_required_space),
++                            # plus 50M safety buffer in /usr
++                            ("/usr", 50*1024*1024),
++                            ("/boot", 160*1024*1024),
++                            ("/tmp", 5*1024*1024),   # /tmp for dkms LP: #427035
++                            ("/", 500*1024*1024),     # small safety buffer /
++                            ]:
++            # we are ensuring we have more than enough free space not less
++            if size < 0:
++                continue
++            dir = os.path.realpath(dir)
++            logging.debug("dir '%s' needs '%s' of '%s' (%f)" % (dir, size, fs_free[dir], fs_free[dir].free))
++            fs_free[dir].free -= size
++            fs_free[dir].need += size
++
++        # check for space required violations
++        required_list = {}
++        for dir in fs_free:
++            if fs_free[dir].free < 0:
++                # ensure unicode here (LP: #1172740)
++                free_at_least = apt_pkg.size_to_str(float(abs(fs_free[dir].free)+1))
++                if isinstance(free_at_least, bytes):
++                    free_at_least = free_at_least.decode(
++                        locale.getpreferredencoding())
++                free_needed = apt_pkg.size_to_str(fs_free[dir].need)
++                if isinstance(free_needed, bytes):
++                    free_needed = free_needed.decode(
++                        locale.getpreferredencoding())
++                # make_fs_id ensures we only get stuff on the same
++                # mountpoint, so we report the requirements only once
++                # per mountpoint
++                required_list[make_fs_id(dir)] = FreeSpaceRequired(free_needed, make_fs_id(dir), free_at_least)
++    except Exception as e:
++        logging.error("free space check failed %s",str(e))
++    
++    if len(required_list) > 0:
++        logging.error("Not enough free space: %s" % [str(i) for i in required_list])
++        raise UpdateBaseError(ERROR_NOT_DISK_SPACE)
++    else:
++        logging.info("Check: Enough free space For system update...")
++        
++    return True
+\ No newline at end of file
+diff --git a/backend-immutable/SystemUpdater/UpdateManager.py b/backend-immutable/SystemUpdater/UpdateManager.py
+index eb55736..31affd5 100644
+--- a/backend-immutable/SystemUpdater/UpdateManager.py
++++ b/backend-immutable/SystemUpdater/UpdateManager.py
+@@ -4,7 +4,9 @@ import os
+ import json
+ import subprocess
+ import dbus,time,sys
++import traceback
+ import logging
++import uuid
+ from .Core.errors import *
+ from .Core.enums import *
+ from .Core.loop import mainloop
+@@ -12,25 +14,23 @@ from gettext import gettext as _
+ from dbus.mainloop.glib import DBusGMainLoop
+ DBusGMainLoop(set_as_default=True)
+ from .Core.Database import Sqlite3Server
++from .Core.MyCache import MyCache
++from SystemUpdater.constants import OUTPUT_JSON_PATH,SYSTEM_UPDATE_GROUPS
++from .UpdatesAvailable import Transaction
++from .push_update import update_important
++from SystemUpdater.configs import settings
+ from .backend.BackendOstreeNext import UpdateBackend,DownloadBackend,DeployBackend,RollbackBackend,LoadCacheBackend
+ from .UpdateManagerDbus import UpdateManagerDbusController,UPDATER_DBUS_INTERFACE,UPDATER_DBUS_PATH,UPDATER_DBUS_SERVICE
+-from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
+-from .Core.MyCache import MyCache
+-from .UpdatesAvailable import UpdatesAvailable
+ from SystemUpdater.Core.DataAcquisition import get_east_8_time
+ 
+-OUTPUT_JSON_PATH = '/var/cache/kylin-system-updater/json/'
+-SYSTEM_UPDATE_GROUPS = "kylin-update-desktop-system"
+-
+ class UpdateManager():
+     def __init__(self,options):
+         try:
+             self.options = options
+             self._check_conf_dir()
+             self.cache = MyCache()
+-            self.trans = UpdatesAvailable()
++            self.trans = Transaction()
+             self.sqlite3_server = Sqlite3Server(self)
+-            self.configs_uncover = UpgradeConfig(defaults_conf="/etc/kylin-system-updater/system-updater-defaults.conf")
+             self.bus = dbus.SystemBus()
+             self.dbus_send = self._setup_dbus(self.bus)
+ 
+@@ -47,12 +47,42 @@ class UpdateManager():
+         except KeyboardInterrupt:
+             self.dbus_send.Quit(None)
+ 
++    def create_trans(self, role, sender):
++        tid = uuid.uuid4().hex
++        trans = Transaction(tid, role, sender)
++        self.trans = trans
++        return trans
++
+     def start_cancel(self):
+         if self.trans:
+             self.trans.cancellable.cancel()
+ 
+     #进行更新的操作
+-    def start_update(self):
++    def start_update(self,trans):
++        try:
++            # if settings.get("update_source",True):
++            #     def _update_important_success(push_list):
++            #         trans.push_list = push_list
++            #         self.start_update_cache(trans)
++
++            #     update_important(self.bus,reply_handler=_update_important_success,error_handler=self._update_error_handler)
++            #     return
++            self.start_update_cache(trans)
++        except UpdateBaseError as excep:
++            self._update_error_handler(excep.code)
++        except UpdateProgressExit:
++            pass
++        except Exception as e:
++            logging.error(e)
++            tbk = traceback.format_exc()
++            logging.error(str(tbk))
++            self._update_error_handler(ERROR_PROGRAM_EXCEPTION)
++
++    def _update_error_handler(self,error_code):
++        self.dbus_send.UpdateDetectFinishedNext(False,[''],error_code)
++
++    #进行更新的操作
++    def start_update_cache(self,trans):
+         try:
+             def _download_info(parent,fetched,requested,bytes_transferred,download_all,bytes_sec):
+                 self.dbus_send.UpdateDownloadInfo(fetched,requested,bytes_transferred,download_all,bytes_sec)
+@@ -60,10 +90,15 @@ class UpdateManager():
+             def _update_finished(parent,trans):
+                 if parent.exit:
+                     # 检查是否可以升级
+-                    if trans.from_revision != trans.new_revision:
+-                        logging.info("Update available refs:%s old-revision:%s to new-revision:%s ",trans.available_refs,trans.from_revision,trans.new_revision)
+-                        self._make_meta_for_panel(trans.available_metadata,OUTPUT_JSON_PATH)
+-                        self.dbus_send.UpdateDetectFinishedNext(True,[SYSTEM_UPDATE_GROUPS],'')
++                    if trans.from_revision and trans.new_revision:
++                        if (trans.from_revision != trans.new_revision and trans.available_refs != trans.deployed_refs) \
++                                or (trans.from_revision != trans.new_revision and trans.push_list):
++                            logging.info("Update available refs:%s old-revision:%s to new-revision:%s ",trans.available_refs,trans.from_revision,trans.new_revision)
++                            self._make_meta_for_panel(trans.available_metadata,OUTPUT_JSON_PATH)
++                            self.dbus_send.UpdateDetectFinishedNext(True,[SYSTEM_UPDATE_GROUPS],'')
++                        else:
++                            logging.info("System is up-to-date refs:%s revision:%s",trans.available_refs,trans.new_revision)
++                            self.dbus_send.UpdateDetectFinishedNext(parent.exit,[],'')
+                     else:
+                         logging.info("System is up-to-date refs:%s revision:%s",trans.available_refs,trans.new_revision)
+                         self.dbus_send.UpdateDetectFinishedNext(parent.exit,[],'')
+@@ -72,10 +107,11 @@ class UpdateManager():
+                 
+                 self.sqlite3_server.insert_into_display("check_time", get_east_8_time()[0:-4])
+ 
++            trans.role = ROLE_UPDATE_CACHE
+             update_backend = UpdateBackend(self,self.options.sysroot,self.options.os)
+             update_backend.connect("transaction-done", _update_finished)
+             update_backend.connect("download-info", _download_info)
+-            update_backend.run(self.trans)
++            update_backend.run(trans)
+         except Exception as e:
+             logging.error(e)
+ 
+@@ -92,6 +128,7 @@ class UpdateManager():
+                 else:
+                     trans.deployable = False
+ 
++            self.trans.role = ROLE_DOWNLOAD_ONLY
+             download_backend = DownloadBackend(self,self.options.sysroot,self.options.os)
+             download_backend.connect("transaction-done", _download_finished)
+             download_backend.connect("download-info", _download_info)
+@@ -106,13 +143,15 @@ class UpdateManager():
+ 
+                 trans.deployable = False
+                 if parent.exit:
+-                    self.configs_uncover.setValue("statusForFinishPrompt","finished_status",INSTALL_SUCCESS_FLAG)
++                    settings["status"] = INSTALL_SUCCESS_FLAG
+                 else:
+-                    self.configs_uncover.setValue("statusForFinishPrompt","finished_status",parent.error_code)
++                    settings["status"] = parent.error_code
++                # 更新内容写入到配置文件
++                settings.save()
+                 
+-                if parent.exit and self.options.sysroot == None:
+-                    self._system_reboot_shutdown(device_status,self.options.prohibit_shutdown)
++                self._system_reboot_shutdown(device_status,self.options.prohibit_shutdown)
+ 
++            self.trans.role = ROLE_DEPLOY_ONLY
+             deploy_backend = DeployBackend(self,self.options.sysroot,self.options.os)
+             deploy_backend.connect("transaction-done", _deploy_finished)
+             deploy_backend.run(self.trans)
+@@ -124,8 +163,7 @@ class UpdateManager():
+             def _rollback_finished(parent,trans):
+                 self.dbus_send.RollbackSysFinishedNext(parent.exit,trans.available_refs,parent.error_code)
+ 
+-                if parent.exit and self.options.sysroot == None:
+-                    self._system_reboot_shutdown("reboot",self.options.prohibit_shutdown)
++                self._system_reboot_shutdown("reboot",self.options.prohibit_shutdown)
+ 
+             rollback_backend = RollbackBackend(self,self.options.sysroot,self.options.os)
+             rollback_backend.connect("transaction-done", _rollback_finished)
+@@ -133,38 +171,12 @@ class UpdateManager():
+         except Exception as e:
+             logging.error(e)
+ 
+-    def start_deb_install(self, deb_path = "", _check_local_dep = False, _auto_satisfy = False, source = '', sender=None):
+-        try:
+-            kareiInterface = dbus.Interface(dbus.SystemBus().get_object('org.kylin.kare', '/org/kylin/kare'),
+-                                            dbus_interface='org.kylin.kare')
+-            logging.info("kare install:%s", deb_path)
+-            kareRet = kareiInterface.install ("openkylin2.0", deb_path)
+-
+-            if kareRet:
+-                logging.info("kare install call success:%s", deb_path)
+-                self.sqlite3_server.transaction_manager.start_transaction(deb_path, 30)
+-            else:
+-                self.dbus_send.InstalldebFinished(False,'kare install call error','')
+-        except Exception as e:
+-            logging.error("kare install error:%s", str(e))
+-            self.dbus_send.InstalldebFinished(False, str(e), 'kare install call error')
+-
+-    def start_purge_pkgs(self,pkgs_list,sender=None):
+-        try:
+-            kareiInterface = dbus.Interface(dbus.SystemBus().get_object('org.kylin.kare', '/org/kylin/kare'),
+-                                            dbus_interface='org.kylin.kare')
+-            for pl in pkgs_list:
+-                logging.info("kare remove: %s", pl)
+-                kareRet = kareiInterface.remove(pl)
+-
+-                if kareRet:
+-                    logging.info("kare remove call success:%s", pl)
+-                    self.sqlite3_server.transaction_manager.start_transaction(pl, 10)
+-                else:
+-                    self.dbus_send.PurgePackagesFinished (False,'kare remove call error','')
+-        except Exception as e:
+-            logging.error("kare remove error:%s", str(e))
+-            self.dbus_send.PurgePackagesFinished (False,'kare remove error','')
++    def require_shutdown_install(self):
++        # 检测当前是否准备安装更新
++        if self.trans.deployable is True:
++            return 1,0
++        else:
++            return 0,0
+ 
+     def _make_meta_for_panel(self,data,output_path):
+         groups_base_info = {}
+@@ -179,12 +191,16 @@ class UpdateManager():
+             groups_base_info.update({"update-type":data.setdefault("update-type",SYSTEM_UPDATE_GROUPS)})
+ 
+             update_name = {"zh_CN":data.setdefault("update-name_zh_CN","系统更新"),"en_US":data.setdefault("update-name_en_US","System update")}
+-
+             groups_base_info.update({"update-name":update_name})
+-            groups_base_info.update({"description":data.setdefault("description","")})
+-            groups_base_info.update({"changelog":data.setdefault("changelog","")})
+-            groups_base_info.update({"total_download_size":int(data.setdefault("ostree.incrementsize",0))})
+-            groups_base_info.update({"total_install_size":int(data.setdefault("ostree.incrementsize",0))})
++
++            description_name = {"zh_CN":data.setdefault("description",""),"en_US":data.setdefault("description","")}
++            groups_base_info.update({"description":description_name})
++
++            changlog = {"zh_CN":data.setdefault("changelog",""),"en_US":data.setdefault("changelog","")}
++            groups_base_info.update({"changelog":changlog})
++            
++            groups_base_info.update({"total_download_size":int(data.setdefault("download-size",0))})
++            groups_base_info.update({"total_install_size":int(data.setdefault("install-size",0))})
+             groups_base_info.update({"icon":data.setdefault("icon","/usr/share/upgrade/icon/kylin-update-desktop-system.png")})
+ 
+             output_json.update(groups_base_info)
+@@ -225,7 +241,7 @@ class UpdateManager():
+             logging.info("Initiate dbus success ...")
+             return  UpdateManagerDbusController(self,bus,bus_name)
+         except dbus.exceptions.NameExistsException:
+-            if self.options.replace is False:
++            if not settings.get("replace",False):
+                 logging.critical("Another daemon is already running")
+                 sys.exit(1)
+             logging.warning("Replacing already running daemon")
+diff --git a/backend-immutable/SystemUpdater/UpdateManagerDbus.py b/backend-immutable/SystemUpdater/UpdateManagerDbus.py
+index f525069..b5ede1d 100755
+--- a/backend-immutable/SystemUpdater/UpdateManagerDbus.py
++++ b/backend-immutable/SystemUpdater/UpdateManagerDbus.py
+@@ -6,13 +6,16 @@ import dbus.service
+ import logging
+ from gettext import gettext as _
+ from .Core.loop import mainloop
+-import SystemUpdater.Core.enums as enums
+ from SystemUpdater.Core.errors import *
+ from SystemUpdater.Core.enums import *
+ from xml.etree import ElementTree
+ import locale
+ from gettext import ngettext
+ from math import ceil
++import subprocess 
++from SystemUpdater.configs import settings
++from SystemUpdater.packageManager.pmWorker import *
++
+ UPDATER_DBUS_INTERFACE = 'com.kylin.systemupgrade.interface'
+ UPDATER_DBUS_PATH = '/com/kylin/systemupgrade'
+ UPDATER_DBUS_SERVICE = 'com.kylin.systemupgrade'
+@@ -107,7 +110,6 @@ class UpdateManagerDbusController(dbus.service.Object):
+         self.cache = parent.cache
+         self.bus = bus
+         self.prohibit_list = []
+-        self.configs_uncover = parent.configs_uncover
+         self.database = self.parent.sqlite3_server
+ 
+         self.now_working = self.ACTION_DEFUALT_STATUS
+@@ -143,8 +145,8 @@ class UpdateManagerDbusController(dbus.service.Object):
+                 sender_name = get_proc_from_dbus_name(sender)
+ 
+                 logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' UpdateDetect sender:%s...',sender_name)
+-                self._check_prohibit_user(sender_name)
+-                self.parent.start_update()
++                trans = self.parent.create_trans(ACTION_DEFUALT_STATUS,sender_name)
++                self.parent.start_update(trans)
+                 self.now_working = self.ACTION_UPDATE
+                 return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
+         except Exception as e:
+@@ -153,7 +155,7 @@ class UpdateManagerDbusController(dbus.service.Object):
+ 
+     #更新 信号
+     def UpdateDetectFinishedNext(self,success,upgrade_group,error_code=''):
+-        self.UpdateDetectFinished(success,upgrade_group,error_code,get_error_description_from_enum(error_code))
++        self.UpdateDetectFinished(success,upgrade_group,get_error_num_from_enum(error_code),get_error_description_from_enum(error_code))
+ 
+     @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='basss')
+     def UpdateDetectFinished(self, success, upgrade_group,error_code='',error_desc=''):
+@@ -170,7 +172,7 @@ class UpdateManagerDbusController(dbus.service.Object):
+             sender_name = get_proc_from_dbus_name(sender)
+ 
+             logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' UpdateDownloadAll sender:%s...',sender_name)
+-            self._check_prohibit_user(sender_name)
++            # self._check_prohibit_user(sender_name)
+             self.parent.start_download()
+             self.now_working = self.ACTION_DOWNLOADONLY
+             return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
+@@ -180,7 +182,7 @@ class UpdateManagerDbusController(dbus.service.Object):
+         
+     # 下载信号
+     def UpdateDownloadFinishedNext(self,success,upgrade_group,error_code=''):
+-        self.UpdateDownloadFinished(success,upgrade_group,error_code,get_error_description_from_enum(error_code))
++        self.UpdateDownloadFinished(success,upgrade_group,get_error_num_from_enum(error_code),get_error_description_from_enum(error_code))
+ 
+     @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='basss')
+     def UpdateDownloadFinished(self, success, upgrade_group,error_code='',error_desc=''):
+@@ -189,7 +191,7 @@ class UpdateManagerDbusController(dbus.service.Object):
+                     success,upgrade_group, error_code,error_desc)
+ 
+     #发送下载包信息 fix bug 字节大小改成u 无符号32位
+-    @dbus.service.signal(UPDATER_DBUS_INTERFACE, signature='iiuui')
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE, signature='iitti')
+     def UpdateDownloadInfo(self,current_items, total_items, currenty_bytes, total_bytes, current_cps):
+         logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" UpdateDownloadInfo current_items = %d, total_items = %d, currenty_bytes = %s, total_bytes = %s, current_cps = %s/s",
+                     current_items, total_items, \
+@@ -205,6 +207,26 @@ class UpdateManagerDbusController(dbus.service.Object):
+ 
+     #  =============================== 部署 =============================== */
+ 
++    # V10版本旧接口名称,内容和DeployLatestUpdate一样
++    @dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='s',out_signature='is',sender_keyword='sender')
++    def TriggerInstallOnShutdown(self,mode,sender=None):
++        try:
++            #处于更新和升级中的话 不进行更新
++            if self.now_working != ACTION_DEFUALT_STATUS:
++                logging.warning('DeployLatestUpdate In the process of Updating or Upgrading...')
++                return self.RETURN_BUSY_STATE,self.RETURN_BUSY_DESC
++            else:
++                sender_name = get_proc_from_dbus_name(sender)
++
++                logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' DeployLatestUpdate sender:%s...',sender_name)
++                # self._check_prohibit_user(sender_name)
++                self.parent.start_deploy(str(mode))
++                self.now_working = self.ACTION_DEPLOY
++                return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
++        except Exception as e:
++            logging.error(str(e))
++            return self.RETURN_UNKNOWN_CODE,str(e)
++
+     @dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='s',out_signature='is',sender_keyword='sender')
+     def DeployLatestUpdate(self,mode,sender=None):
+         try:
+@@ -216,7 +238,7 @@ class UpdateManagerDbusController(dbus.service.Object):
+                 sender_name = get_proc_from_dbus_name(sender)
+ 
+                 logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' DeployLatestUpdate sender:%s...',sender_name)
+-                self._check_prohibit_user(sender_name)
++                # self._check_prohibit_user(sender_name)
+                 self.parent.start_deploy(str(mode))
+                 self.now_working = self.ACTION_DEPLOY
+                 return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
+@@ -226,7 +248,7 @@ class UpdateManagerDbusController(dbus.service.Object):
+ 
+     def DeployUpdatFinishedNext(self,success,upgrade_group,error_code=''):
+         self.database.insert_info(success,error_code)
+-        self.DeployUpdatFinished(success,upgrade_group,error_code,get_error_description_from_enum(error_code))
++        self.DeployUpdatFinished(success,upgrade_group,get_error_num_from_enum(error_code),get_error_description_from_enum(error_code))
+ 
+     @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='basss')
+     def DeployUpdatFinished(self, success, upgrade_group,error_code='',error_desc=''):
+@@ -300,10 +322,11 @@ class UpdateManagerDbusController(dbus.service.Object):
+         try:
+             sender_name = get_proc_from_dbus_name(sender)
+ 
+-            status = self.configs_uncover.getWithDefault("statusForFinishPrompt", "finished_status",INSTALL_DEFAULT_FLAG)
++            status = settings.get("status")
+             logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' ChcekPopupOnPoweroffInstalled sender:%s  status:%s ...',sender_name,status)
+             if status != INSTALL_DEFAULT_FLAG:
+-                self.configs_uncover.setValue("statusForFinishPrompt","finished_status",INSTALL_DEFAULT_FLAG)
++                settings["status"] = INSTALL_DEFAULT_FLAG
++                settings.save()
+             return status
+         except Exception as e:
+             logging.error(str(e))
+@@ -324,71 +347,161 @@ class UpdateManagerDbusController(dbus.service.Object):
+         #                                             sender_name,os_version, update_version)
+         return os_version,update_version
+ 
+-    @dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='ssbbs',out_signature='is',sender_keyword='sender')
++    #  =============================== 包安装卸载 =============================== */
++    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='ssbbs', out_signature='is', sender_keyword='sender')
+     def InstallDebFile(self,source = "unKnown", path = "", _check_local_dep = False, _auto_satisfy = False, user_lang = '', sender=None):
+         try:
+-            if self.now_working != ACTION_DEFUALT_STATUS:
+-                logging.warning('PurgePackages In the process of Updating or Upgrading...')
++            sender_name = get_proc_from_dbus_name(sender)
++
++            if self.now_working != self.ACTION_DEFUALT_STATUS:
++                logging.warning('Updater In the process of Upgrading, ignore \'%s\' InstallDebFile(%s) request ...', \
++                                sender_name, path)
+                 return self.RETURN_BUSY_STATE,self.RETURN_BUSY_DESC
+ 
+-            #当传入为空时 直接返回
+             if str(user_lang) == '':
+                 logging.info("The incoming language is null...")
+ 
+-            check_local_dep = bool(_check_local_dep)
+-            auto_satisfy = bool(_auto_satisfy)
+-            deb_path = str(path)
++            check_local_dep     = bool(_check_local_dep)
++            auto_satisfy        = bool(_auto_satisfy)
++            deb_path            = str(path)
+ 
+-            sender_name = get_proc_from_dbus_name(sender)
+-            self._check_prohibit_user(sender_name)
+             logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' InstallDebFile and check_local_dep:%r, auto_satisfy:%r, current_lang:%s , InstallDebFile sender: %s .',\
+-                                        check_local_dep,auto_satisfy,user_lang,sender_name)
+-            logging.info("Will install: %s.",path)
+-            self.parent.start_deb_install(deb_path, _check_local_dep, _auto_satisfy, source, sender)
++                                        check_local_dep, auto_satisfy, user_lang, sender_name)
++            logging.info("Will install: %s.", path)
++
++            if not hasattr(self.parent, 'pmworker') or self.parent.pmworker is None:
++                self.parent.pmworker = PmWorker(self.parent)
++
++            self.parent.pmworker.start_deb_install(deb_path, _check_local_dep, _auto_satisfy, source, sender)
+             return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
+         except Exception as e:
+             logging.error(str(e))
+             return self.RETURN_UNKNOWN_CODE,str(e)
+ 
+-    @dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='asss',out_signature='is',sender_keyword='sender')
+-    def PurgePackages(self,_purge_list,cur_user,user_lang = '',sender=None):
++    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='as', out_signature='is', sender_keyword='sender')
++    def InstallPackages(self, pkg_list = [], sender=None):
+         try:
+-            if self.now_working != ACTION_DEFUALT_STATUS:
+-                logging.warning('PurgePackages In the process of Updating or Upgrading...')
++            sender_name = get_proc_from_dbus_name(sender)
++
++            if self.now_working != self.ACTION_DEFUALT_STATUS:
++                logging.warning('Updater In the process of Upgrading, ignore \'%s\' InstallPackages request ...', \
++                                sender_name)
+                 return self.RETURN_BUSY_STATE,self.RETURN_BUSY_DESC
+ 
+-            if str(user_lang) == '':
+-                logging.info("The incoming language is null...")
++            logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' InstallPackages: %s .',\
++                                                                        ",".join(pkg_list))
+ 
+-            purge_list = [str(pkg) for pkg in _purge_list]
++            if not hasattr(self.parent, 'pmworker') or self.parent.pmworker is None:
++                self.parent.pmworker = PmWorker(self.parent)
++
++            self.parent.pmworker.start_back_upgrade(pkg_list, sender)
++
++            return self.RETURN_SUCCESS_CODE, self.RETURN_SUCCESS_DESC
++        except Exception as e:
++            logging.error(str(e))
++            return self.RETURN_UNKNOWN_CODE, str(e)
++
++    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='asss', out_signature='is', sender_keyword='sender')
++    def PurgePackages(self, _purge_list, cur_user, user_lang = '', sender=None):
++        try:
+             sender_name = get_proc_from_dbus_name(sender)
++            purge_list = [str(pkg) for pkg in _purge_list]
++
++            if self.now_working != self.ACTION_DEFUALT_STATUS:
++                logging.warning('Updater In the process of Upgrading, ignore \'%s\' PurgePackages(%s) request ...', \
++                                sender_name, purge_list)
++                return self.RETURN_BUSY_STATE,self.RETURN_BUSY_DESC
++
+             logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' PurgePackages Sender:%s and purge list is:%s...',sender_name, purge_list)
+-            self._check_prohibit_user(sender_name)
+ 
+-            # if True:
+-            #     #需要对aptdeamon加这两个环境变量 才可以提示弹窗
+-            #     self.set_aptdeamon_environ("XAUTHORITY","/home/"+str(cur_user)+"/.Xauthority")
+-            #     self.set_aptdeamon_environ("DISPLAY",":0")
++            if not hasattr(self.parent, 'pmworker') or self.parent.pmworker is None:
++                self.parent.pmworker = PmWorker(self.parent)
+ 
+-            self.parent.sqlite3_server.current_purge_pkgs = purge_list
+-            self.parent.start_purge_pkgs(purge_list, sender)
++            self.parent.pmworker.start_purge_pkgs(purge_list, sender)
+             return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
+         except Exception as e:
+             logging.error(str(e))
+             return self.RETURN_UNKNOWN_CODE,str(e)
+-    
++
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='basss')
++    def UpdateInstallFinished(self, success, upgrade_group, error_string='', error_desc=''):
++        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='bss')
+-    def InstalldebFinished(self, success,error_string='',error_desc=''):
+-        logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " InstalldebFinished success = %r , error_string = %s , error_desc = %s ",\
++    def PurgePackagesFinished(self, success,error_string='',error_desc=''):
++        logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " PurgePackagesFinished success = %r , error_string = %s , error_desc = %s ",\
+                     success,error_string,error_desc)
++
++    #卸载进度信息 0~100 进度信息 101为非预期的信号
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='iss')
++    def PurgePkgStatusChanged(self,progress,status,current_details):
++        logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" PurgePkgStatusChanged progress = %d , status = %s ,current_details = %s",\
++            progress,status,current_details)
+     
++    #卸载完成的信号,包含当前正在卸载的包名
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bsss')
++    def PurgePackagesFinishedWithPkgname(self, success,error_string='',error_desc='',current_pkg=''):
++        logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " PurgePackagesFinishedWithPkgname success = %r , error_string = %s , error_desc = %s , current purge package = %s" ,\
++                    success,error_string,error_desc,current_pkg)
++    
++    #卸载完成的信号
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bssss')
++    def PurgePackagesFinishedWithErrCode(self, success,error_string='',error_desc='',current_pkg='',error_code=''):
++        logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " PurgePackagesFinishedWithErrCode success = %r , error_string = %s , error_desc = %s , current purge package = %s , error_code = %s",\
++                    success,error_string,error_desc,current_pkg,error_code)
++
++    #卸载进度信息 0~100 进度信息 101为非预期的信号,包含当前正在卸载的包名
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='isss')
++    def PurgePkgStatusChangedWithPkgname(self,progress,status,current_details,current_pkg=''):
++        logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" PurgePkgStatusChangedWithPkgname progress = %d , status = %s ,current_details = %s, current purge package = %s",\
++            progress,status,current_details,current_pkg)
++
++    #安装deb包完成的信号
+     @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bss')
+-    def PurgePackagesFinished(self, success,error_string='',error_desc=''):
+-        logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " PurgePackagesFinished success = %r , error_string = %s , error_desc = %s ",\
++    def InstalldebFinished(self, success,error_string='',error_desc=''):
++        logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " InstalldebFinished success = %r , error_string = %s , error_desc = %s ",\
+                     success,error_string,error_desc)
+ 
++    #安装deb包完成的信号
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bsss')
++    def InstalldebFinishedWithErrCode(self, success,error_string='',error_desc='',error_code=''):
++        logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " InstalldebFinishedWithErrCode success = %r , error_string = %s , error_desc = %s , error_code = %s",\
++                    success,error_string,error_desc,error_code)
++        
++    #安装进度信息 0~100 进度信息 101为非预期的信号
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='iss')
++    def InstalldebStatusChanged(self,progress,status,current_details):
++        logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" InstalldebStatusChanged progress = %d , status = %s ,current_details = %s",\
++            progress,status,current_details)
++
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='is')
++    def EnvBuildStatusChanged(self, progress, status):
++        logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" EnvBuildStatusChanged progress = %d , status = %s",\
++            progress,status)
++
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bs')
++    def EnvBuildStatusFinished(self, progress, status):
++        logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" EnvBuildStatusFinished progress = %d , status = %s",\
++            progress,status)
++
+     WRITABLE_PROPERTIES = ()
+ 
++    #检查是否需要安装或者重启安装的请求
++    @dbus.service.method(UPDATER_DBUS_INTERFACE,out_signature='is',sender_keyword='sender')
++    def CheckInstallRequired(self,sender=None):
++        try:
++            sender_name = get_proc_from_dbus_name(sender)
++            need_install,install_time = self.parent.require_shutdown_install()
++            logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' CheckInstallRequired need_install:%s install_time:%s sender_name: %s...',\
++                                                need_install,install_time,sender_name)
++
++            return need_install,str(install_time)
++        except Exception as e:
++            logging.error(str(e))
++            return 0,"0"
++
+     # pylint: disable-msg=C0103,C0322
+     @dbus.service.signal(dbus_interface=dbus.PROPERTIES_IFACE,
+                         signature="sa{sv}as")
+@@ -498,7 +611,6 @@ class UpdateManagerDbusController(dbus.service.Object):
+         '''
+         if iface == UPDATER_DBUS_INTERFACE:
+             if name == "ShutdownInstall":
+-                self.parent.configs_uncover.setValue("InstallMode","shutdown_install",str(bool(value)))
+             elif name == "P2pBootstrap":
+                 self.parent.apt_p2p_config.set_bootstrap(str(value))
+             else:
+@@ -518,3 +630,28 @@ class UpdateManagerDbusController(dbus.service.Object):
+                     }
+         else:
+             return {}
++
++    @dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='s',out_signature='b',sender_keyword='sender')
++    def MountSquashfs(self,squashfs,sender=None):
++        logging.info("mount squashfs:%s"%squashfs)
++        ret = True
++        if(os.path.exists(squashfs)):
++            name=os.path.splitext(squashfs)
++            logging.info("file extension name:%s"%name[1])
++            if(name[1].lower()==".squashfs"):
++                try:                    
++                    mountpath = "/media/OfflineSource"
++                    cmd="cat /proc/mounts|grep -q %s && umount %s"%(mountpath,mountpath)
++                    ret1=subprocess.run(cmd,shell=True).returncode
++                    logging.info("umount return code:%d"%ret1)
++                    cmd1 = "mkdir -p %s && mount -o loop %s %s"%(mountpath,squashfs,mountpath)
++                    ret2=subprocess.run(cmd1,shell=True).returncode                                                     
++                    logging.info("mount ret:%d"%ret2)
++                    if (ret2==0):
++                        pass
++                    else:
++                        ret=False
++                except Exception as e:
++                    logging.error(e)
++                    ret = False
++        return ret
+\ No newline at end of file
+diff --git a/backend-immutable/SystemUpdater/UpdatesAvailable.py b/backend-immutable/SystemUpdater/UpdatesAvailable.py
+index 3ed3076..ecf276b 100644
+--- a/backend-immutable/SystemUpdater/UpdatesAvailable.py
++++ b/backend-immutable/SystemUpdater/UpdatesAvailable.py
+@@ -3,26 +3,28 @@
+ import os
+ import json
+ import logging
++import collections
+ from gi.repository import Gio
+ from gettext import gettext as _
+ from SystemUpdater.Core.errors import *
+ from SystemUpdater.Core.enums import *
++from gi.repository import GObject, GLib
+ 
+-class UpdatesAvailable():
+-    """
+-    Represent the (potentially partial) results of an unattended-upgrades
+-    run
+-    """
+-
++class Transaction():
+     # 更新的缓存数据保存位置 
+     UPDATE_AVAILABLE_DATA = "/var/cache/kylin-system-updater/update_available_data.json"
+ 
+-    def __init__(self):
++    def __init__(self,tid=None, role=None, sender=None):
+         self.from_revision = None
+         self.new_revision = None
+         self.available_refs = None
+-        self.available_metadata = None
+-
++        self.deployed_refs = None
++        self.available_repo = None
++        self.push_list = []
++        self.available_metadata = {}
++        self.tid = tid
++        self.role = ROLE_UNSET
++        self.sender = sender
+         self._deployable = False
+ 
+         if os.path.exists(self.UPDATE_AVAILABLE_DATA):
+@@ -36,8 +38,13 @@ class UpdatesAvailable():
+     def _write_local(self):
+         try:
+             output_upgrade = {}
++            output_upgrade.update({"from_revision":self.from_revision})
+             output_upgrade.update({"new_revision":self.new_revision})
+             output_upgrade.update({"available_refs":self.available_refs})
++            output_upgrade.update({"deployed_refs":self.deployed_refs})
++            output_upgrade.update({"available_repo":self.available_repo})
++            # output_upgrade.update({"push_list":self.push_list})
++            output_upgrade.update({"available_metadata":self.available_metadata})
+             output_upgrade.update({"_deployable":self._deployable})
+ 
+             #6 产生JSON文件
+@@ -51,14 +58,18 @@ class UpdatesAvailable():
+         try:
+             with open(self.UPDATE_AVAILABLE_DATA,'r') as f:
+                 data = json.load(f)
+-                self.new_revision = data["new_revision"]
+-                self.available_refs = data["available_refs"]
+-                self._deployable = data["_deployable"]
++                self.from_revision = data.get("from_revision",None)
++                self.new_revision = data.get("new_revision",None)
++                self.available_refs = data.get("available_refs",None)
++                self.deployed_refs = data.get("deployed_refs",None)
++                self.available_repo = data.get("available_repo",None)
++                # self.push_list = data.get("push_list",[])
++                self.available_metadata = data.get("available_metadata",{})
++                self._deployable = data.get("_deployable",False)
+             logging.info("Finished: reading upgrade data from the local file...")
+         except Exception as exc:
+             logging.error(exc)
+ 
+-
+     def _get_deployable(self):
+         return self._deployable
+ 
+@@ -66,4 +77,94 @@ class UpdatesAvailable():
+         self._deployable = state
+         self._write_local()
+ 
+-    deployable = property(_get_deployable, _set_deployable)
+\ No newline at end of file
++    def _set_default(self,state):
++        pass
++
++    def _get_download_size(self):
++        return self.available_metadata.get("download-size",0)
++
++    def _get_install_size(self):
++        return self.available_metadata.get("install-size",0)
++
++    deployable = property(_get_deployable, _set_deployable)
++    dowanload_size = property(_get_download_size, _set_default)
++    install_size = property(_get_install_size, _set_default)
++
++class TransactionQueue(GObject.GObject):
++
++    """Queue for transactions."""
++
++    __gsignals__ = {"queue-changed": (GObject.SignalFlags.RUN_FIRST,
++                                      None,
++                                      ())}
++
++    def __init__(self, worker):
++        """Intialize a new TransactionQueue instance."""
++        GObject.GObject.__init__(self)
++        self._queue = collections.deque()
++        self._proc_count = 0
++        self.worker = worker
++        # Used to keep track of not yet queued transactions
++        self.limbo = {}
++        # self.worker.connect("transaction-done", self._on_transaction_done)
++
++    def __len__(self):
++        return len(self._queue)
++
++    def _emit_queue_changed(self):
++        """Emit the queued-changed signal."""
++        logging.debug("emitting queue changed")
++        self.emit("queue-changed")
++
++    def put(self, tid):
++        """Add an item to the queue."""
++        trans = self.limbo.pop(tid)
++        if trans._idle_watch is not None:
++            GLib.source_remove(trans._idle_watch)
++        if self.worker.trans:
++            trans.status = enums.STATUS_WAITING
++            self._queue.append(trans)
++        else:
++            self.worker.run(trans)
++        self._emit_queue_changed()
++
++    # def _on_transaction_done(self, worker, trans):
++    #     """Mark the last item as done and request a new item."""
++    #     # FIXME: Check if the transaction failed because of a broken system or
++    #     #       if dpkg journal is dirty. If so allready queued transactions
++    #     #       except the repair transactions should be removed from the queue
++    #     if trans.exit in [enums.EXIT_FAILED, enums.EXIT_CANCELLED]:
++    #         if trans.exit == enums.EXIT_FAILED:
++    #             exit = enums.EXIT_PREVIOUS_FAILED
++    #         else:
++    #             exit = enums.EXIT_CANCELLED
++    #         _trans = trans.after
++    #         while _trans:
++    #             self.remove(_trans)
++    #             _trans.exit = exit
++    #             msg = enums.get_role_error_from_enum(trans.role)
++    #             _trans.status_details = msg
++    #             _trans = _trans.after
++    #     try:
++    #         next_trans = self._queue.popleft()
++    #     except IndexError:
++    #         logging.debug("There isn't any queued transaction")
++    #     else:
++    #         self.worker.run(next_trans)
++    #     self._emit_queue_changed()
++
++    def remove(self, transaction):
++        """Remove the specified item from the queue."""
++        self._queue.remove(transaction)
++        self._emit_queue_changed()
++
++    def clear(self):
++        """Remove all items from the queue."""
++        for transaction in self._queue:
++            transaction._remove_from_connection_no_raise()
++        self._queue.clear()
++
++    @property
++    def items(self):
++        """Return a list containing all queued items."""
++        return list(self._queue)
+\ No newline at end of file
+diff --git a/backend-immutable/SystemUpdater/UpgradeStrategies.py b/backend-immutable/SystemUpdater/UpgradeStrategies.py
+index 6d18d78..954744f 100644
+--- a/backend-immutable/SystemUpdater/UpgradeStrategies.py
++++ b/backend-immutable/SystemUpdater/UpgradeStrategies.py
+@@ -1,38 +1,40 @@
+ # UpdateManager.py
+ # -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
+-import os
+ import sys
+ import time
+ import dbus
+ import logging
+ import dbus.service
+ import traceback
+-from gettext import gettext as _
+ from dbus.mainloop.glib import DBusGMainLoop
+-from gi.repository import GLib
+ DBusGMainLoop(set_as_default=True)
+ 
+-from .UpgradeStrategiesDbus import UpgradeStrategiesDbusController,UPDATER_DBUS_INTERFACE,UPDATER_DBUS_PATH,UPDATER_DBUS_SERVICE
+ from .Core.Database import Sqlite3Server
+ from .Core.loop import mainloop
+-
+ from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
++from .UpgradeStrategiesDbus import UpgradeStrategiesDbusController, \
++                                UPDATER_DBUS_INTERFACE, \
++                                UPDATER_DBUS_PATH, \
++                                UPDATER_DBUS_SERVICE
++from SystemUpdater.packageManager.pmUtils import *
+ 
+ STRATEGY_IDLE_INTERVAL = 2*60
+ STRATEGY_IDLE_TIMEOUT = 6*60
+ class UpgradeStrategies():
+     def __init__(self,options):
+         try:
+-            self.options = options
+-            #dbus
+-            self.dbusController = self._setup_dbus()
+-            #config
+-            self.uuconfigs = UpgradeConfig(datadir = "/var/lib/unattended-upgrades/", name = "unattended-upgrades-policy.conf")
+-            self.sqlite3_server = Sqlite3Server(self, _no_DataMigration=True)
+-            #策略配置接口的超时退出机制
++            self.options            = options
++            self.bus                = dbus.SystemBus ()
++            self.dbus_send          = self._setup_dbus ( self.bus )
++            self.uuconfigs          = UpgradeConfig (
++                                        datadir = "/var/lib/unattended-upgrades/",
++                                        name = "unattended-upgrades-policy.conf" )
++            self.configs_uncover    = UpgradeConfig (
++                                        defaults_conf = "/etc/kylin-system-updater/system-updater-defaults.conf" )
++            self.sqlite3_server     = Sqlite3Server ( self, _no_DataMigration=True )
++
+             self.strategy_timestamp = 0
+-            # GLib.timeout_add_seconds(STRATEGY_IDLE_INTERVAL,
+-            #     self._check_strategy_inactivity)
++
+         except Exception as e:
+             logging.error(e)
+             traceback.print_exc()
+@@ -43,12 +45,11 @@ class UpgradeStrategies():
+         try:
+             mainloop.run()
+         except KeyboardInterrupt:
+-            self.dbusController.Quit(None)
++            self.dbus_send.Quit(None)
+ 
+-    def _setup_dbus(self):
++    def _setup_dbus(self, bus):
+         # check if there is another g-a-i already and if not setup one
+         # listening on dbus
+-        bus = dbus.SystemBus()
+         try:
+             bus_name = dbus.service.BusName(UPDATER_DBUS_SERVICE,
+                                             bus,
+@@ -96,6 +97,6 @@ class UpgradeStrategies():
+         #超时退出
+         if self.strategy_timestamp != 0 and  time.time() - self.strategy_timestamp > STRATEGY_IDLE_TIMEOUT:
+             logging.warning("Quitting due to inactivity")
+-            self.dbusController.Quit(None)
++            self.dbus_send.Quit(None)
+             return False
+-        return True
+\ No newline at end of file
++        return True
+diff --git a/backend-immutable/SystemUpdater/UpgradeStrategiesDbus.py b/backend-immutable/SystemUpdater/UpgradeStrategiesDbus.py
+index 1691052..1ab788d 100644
+--- a/backend-immutable/SystemUpdater/UpgradeStrategiesDbus.py
++++ b/backend-immutable/SystemUpdater/UpgradeStrategiesDbus.py
+@@ -6,7 +6,9 @@ import logging
+ import subprocess
+ from gettext import gettext as _
+ from .Core.loop import mainloop
+-from SystemUpdater.Core.utils import get_proc_from_dbus_name
++from SystemUpdater.Core.DbusControl import DbusControl
++from SystemUpdater.packageManager.pmUtils import *
++from SystemUpdater.packageManager.pmWorker import *
+ 
+ UPDATER_DBUS_INTERFACE = 'com.kylin.UpgradeStrategies.interface'
+ UPDATER_DBUS_PATH = '/com/kylin/UpgradeStrategies'
+@@ -45,20 +47,40 @@ UU_UPGRADE_MODE_BEFORE_SHUTDOWN = 3
+ class UpgradeStrategiesDbusController(dbus.service.Object):
+     """ this is a helper to provide the UpdateManagerIFace """
+ 
+-    P2P_DEDAULT_PATH = "/etc/default/apt-p2p"
+-    RETURN_SUCCESS_CODE = 0
+-    RETURN_SUCCESS_DESC = ""
++    ACTION_DEFUALT_STATUS   =-1
++    ACTION_UPDATE           = 0
++    ACTION_DOWNLOADONLY     = 1
++    ACTION_DEPLOY           = 2
++    ACTION_ROLLBACK         = 3
+ 
+-    RETURN_UNKNOWN_CODE = -1
+-    RETURN_UNKNOWN_DESC = ""
++    RETURN_BUSY_STATE       = 1
++    RETURN_BUSY_DESC        = "In the process of updating or Upgrading..."
++
++    P2P_DEDAULT_PATH        = "/etc/default/apt-p2p"
++    RETURN_SUCCESS_CODE     = 0
++    RETURN_SUCCESS_DESC     = ""
++
++    RETURN_UNKNOWN_CODE     =-1
++    RETURN_UNKNOWN_DESC     = ""
+ 
+     def __init__(self, parent, bus_name,
+                 object_path=UPDATER_DBUS_PATH):
+         dbus.service.Object.__init__(self, bus_name, object_path)
+-        self.parent = parent
+-        self.bus = dbus.SystemBus()
++        self.parent         = parent
++        self.bus            = dbus.SystemBus()
+ 
+-        self.transaction = None
++        self.transaction    = None
++        self.now_working    = self.ACTION_DEFUALT_STATUS
++
++        self.prohibit_list  = []
++        if not self.parent.options.debug:
++            self.prohibit_list = ["dbus-send","gdbus"]
++        
++        self.dbus_control = DbusControl(self.bus,parent.options.debug)
++    
++    def _check_prohibit_user(self, sender_name):
++        if sender_name in self.prohibit_list:
++            raise dbus.exceptions.DBusException("ERROR: You are not allowed to perform this action.")
+ 
+     def __check_change__(self, _config = None, _section = "", _option = "", _value = ""):
+         if _config == None:
+@@ -73,8 +95,7 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     def Quit(self, caller_name):
+         """Request a shutdown of the daemon."""
+         #如果在下载就请求 取消
+-        logging.info("Quitting was requested")
+-        logging.debug("Quitting main loop...")
++        logging.info("UpgradeStrategies service quitting...")
+         mainloop.quit()
+         logging.debug("Exit")
+ 
+@@ -82,7 +103,7 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='is',sender_keyword='sender')
+     def ChangingP2PStatus(self,_status,sender = None):
+         status = str(_status)
+-        sender_name = get_proc_from_dbus_name(sender)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' ChangingP2PStatus, _status = %s , sender name: %s',status,sender_name)
+         
+         if os.path.exists(self.P2P_DEDAULT_PATH):
+@@ -155,7 +176,7 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='b', out_signature='b',sender_keyword='sender')
+     def SetUpgradeStrategyState(self,state,sender=None):
+         state=bool(state)
+-        sender_name = get_proc_from_dbus_name(sender)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' SetUpdateStrategyState, upgrade strategy state is %r, sender name: %s .',state,sender_name)
+         try:
+             if state:
+@@ -175,7 +196,7 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='b',sender_keyword='sender')
+     def SetUpgradeMode(self, mode, sender = None):
+         _mode = str(mode)
+-        sender_name = get_proc_from_dbus_name(sender)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' SetUpgradeMode, mode: %s , sender:%s .',_mode,sender_name)                        
+         try:
+             if not self.__check_change__(self.parent.uuconfigs, "updateStrategiesManager", "installType", _mode):
+@@ -191,7 +212,7 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     def SetPreDownloadState(self, _state, _time, sender = None):
+         state = bool(_state)
+         time  = str(_time)
+-        sender_name = get_proc_from_dbus_name(sender)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' SetPreDownloadState, state is %r, time: %s, sender name: %s .',state,time,sender_name)
+         try:
+             if state:
+@@ -214,7 +235,7 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='i', out_signature='b',sender_keyword='sender')
+     def SetUpdateDays(self, days, sender = None):
+         _days = int(days)
+-        sender_name = get_proc_from_dbus_name(sender)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' SetUpdateDays, days: %d , sender:%s .'\
+                         ,_days,sender_name)
+         try:
+@@ -230,7 +251,7 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='bs',sender_keyword='sender')
+     def SetAutoUpgradeRandomRange(self,randomRange,sender=None):
+         _randomRange = str(randomRange)
+-        sender_name = get_proc_from_dbus_name(sender)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' SetAutoUpgradeRandomRange will be set value %s, sender: %s .',\
+                             _randomRange,sender_name)
+         try:
+@@ -246,7 +267,7 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     def SetAutomaticReboot(self, status, reboot_time, sender = None):
+         _state = bool(status)
+         _reboot_time  = str(reboot_time)
+-        sender_name = get_proc_from_dbus_name(sender)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' SetAutomaticReboot, status is %r, reboot_time: %s, sender name: %s .'\
+                         ,_state,_reboot_time,sender_name)
+         try:
+@@ -267,9 +288,10 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+         return True
+ 
+     ## dbus接口: 开启关闭自动更新功能
+-    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='b', out_signature='b')
+-    def SetAutoUpgradeState(self, _state):
++    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='b', out_signature='b', sender_keyword='sender')
++    def SetAutoUpgradeState(self, _state, sender):
+         state = bool(_state)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' SetAutoUpgradeState, state is %r ...',state)
+         try:
+             if state:
+@@ -290,9 +312,10 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+         return True
+ 
+     ## dbus接口: 设置自动更新策略
+-    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='is', out_signature='b')
+-    def SetAutoUpgradeMode(self, mode, time):
++    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='is', out_signature='b', sender_keyword='sender')
++    def SetAutoUpgradeMode(self, mode, time, sender):
+         _time = str(time)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' SetAutoUpgradeMode, mode is %s, time is %s ...',mode,_time)
+         try:
+             if mode == UU_UPGRADE_MODE_AUTOMATIC_DOWNLOAD:
+@@ -326,7 +349,7 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     # # dbus接口:改变apt下载速度
+     @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='sb', out_signature='b',sender_keyword='sender')
+     def SetDownloadspeedMax(self, speed, set,sender = None):
+-        sender_name = get_proc_from_dbus_name(sender)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' SetDownloadspeedMax, speed:%s, set:%r, sender name: %s .'%(speed, set, sender_name))
+         #来重启Aptdeamon
+         if set:
+@@ -357,7 +380,7 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     # # dbus接口:获取apt下载速度
+     @dbus.service.method(UPDATER_DBUS_INTERFACE, out_signature='bs',sender_keyword='sender')
+     def GetDownloadspeedLimitValue(self,sender = None):
+-        sender_name = get_proc_from_dbus_name(sender)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' GetDownloadspeedLimitValue sender: %s .', sender_name)
+         try:
+             download_limit = self.parent.sqlite3_server.select_from_display("download_limit")
+@@ -372,7 +395,7 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     # 是否允许关机前更新
+     @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='ss', out_signature='bs', sender_keyword='sender')
+     def UnattendedUpgradeValue(self, operation, value="false", sender=None):
+-        sender_name = get_proc_from_dbus_name(sender)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' UnattendedUpgradeValue sender:%s ', sender_name)
+         if operation.lower() != "get" and operation.lower() != "set":
+             return False, 'Please input [\"set\", \"value\"] to set. \nor [\"get\"] to get whether updates are allowed before shutdown.'
+@@ -405,9 +428,10 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     #     return True,"success"
+ 
+     # 获取数据库值
+-    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='bss', out_signature='s')
+-    def GetSetDatabaseInfo(self, gs, table, field):
++    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='bss', out_signature='s', sender_keyword='sender')
++    def GetSetDatabaseInfo(self, gs, table, field, sender):
+         Text = 'NULL'
++        sender_name = self.dbus_control.check_sender(sender)
+         try:
+             if gs: #get 
+                 if table == 'display':
+@@ -425,8 +449,9 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+         return Text
+ 
+     ## dbus接口: 发送立即更新的信号
+-    @dbus.service.method(UPDATER_DBUS_INTERFACE, out_signature='b')
+-    def AutoUpgradeAllNow(self):
++    @dbus.service.method(UPDATER_DBUS_INTERFACE, out_signature='b', sender_keyword='sender')
++    def AutoUpgradeAllNow(self, sender):
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' AutoUpgradeAllNow ...')
+         try:
+             self.UpgradeAllNow()
+@@ -435,27 +460,11 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+             return False
+         return True
+ 
+-    # kill 进程
+-    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='i', out_signature='b')
+-    def KillProcessSignal(self, pid):
+-        logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' KillProcessSignal is %d', pid)
+-        try:
+-            # 判断文件是否存在
+-            if (os.path.exists(RUN_UNATTENDED_UPGRADE)):
+-                os.kill(int(pid), 9)
+-                logging.info('%s has been killed', pid)
+-            else:
+-                logging.warning('%s is not exist.', RUN_UNATTENDED_UPGRADE)
+-        except Exception as e:
+-            logging.error(str(e))
+-            return False
+-        return True
+-
+     #设置数据库配置信息
+     @dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='ss',out_signature='b',sender_keyword='sender')
+     def DatabaseInfoSet(self,field_name,field_value,sender=None):
+         Status = False
+-        sender_name = get_proc_from_dbus_name(sender)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' SetDatabaseInfo,field_name:%s,field_value:%s,caller:%s .',\
+                 field_name,field_value,sender_name)
+         Status = self.parent.sqlite3_server.insert_into_display(field_name,field_value)
+@@ -465,12 +474,173 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     @dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='s',out_signature='s',sender_keyword='sender')
+     def DatabaseInfoGet(self,field_name,sender=None):
+         field_value = ''
+-        sender_name = get_proc_from_dbus_name(sender)
++        sender_name = self.dbus_control.check_sender(sender)
+         logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' GetDatabaseInfo field_name:%s caller:%s',field_name,sender_name)
+         field_value = self.parent.sqlite3_server.select_from_display(str(field_name))
+         logging.info("Get field_value:%s",field_value)
+         return field_value
+ 
++    #  =============================== 包安装卸载 =============================== */
++    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='ssbbs', out_signature='is', sender_keyword='sender')
++    def InstallDebFile(self,source = "unKnown", path = "", _check_local_dep = False, _auto_satisfy = False, user_lang = '', sender=None):
++        try:
++            sender_name = self.dbus_control.check_sender(sender)
++
++            if self.now_working != self.ACTION_DEFUALT_STATUS:
++                logging.warning('Updater In the process of Upgrading, ignore \'%s\' InstallDebFile(%s) request ...', \
++                                sender_name, path)
++                return self.RETURN_BUSY_STATE,self.RETURN_BUSY_DESC
++
++            if str(user_lang) == '':
++                logging.info("The incoming language is null...")
++
++            check_local_dep     = bool(_check_local_dep)
++            auto_satisfy        = bool(_auto_satisfy)
++            deb_path            = str(path)
++
++            logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' InstallDebFile and check_local_dep:%r, auto_satisfy:%r, current_lang:%s , InstallDebFile sender: %s .',\
++                                        check_local_dep, auto_satisfy, user_lang, sender_name)
++            logging.info("Will install: %s.", path)
++
++            if not hasattr(self.parent, 'pmworker') or self.parent.pmworker is None:
++                self.parent.pmworker = PmWorker(self.parent)
++
++            self.parent.pmworker.start_deb_install(deb_path, _check_local_dep, _auto_satisfy, source, sender)
++            return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
++        except Exception as e:
++            logging.error(str(e))
++            return self.RETURN_UNKNOWN_CODE,str(e)
++
++    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='as', out_signature='is', sender_keyword='sender')
++    def InstallPackages(self, pkg_list = [], sender=None):
++        try:
++            sender_name = self.dbus_control.check_sender(sender)
++
++            if self.now_working != self.ACTION_DEFUALT_STATUS:
++                logging.warning('Updater In the process of Upgrading, ignore \'%s\' InstallPackages request ...', \
++                                sender_name)
++                return self.RETURN_BUSY_STATE,self.RETURN_BUSY_DESC
++
++            logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' InstallPackages: %s .',\
++                                                                        ",".join(pkg_list))
++
++            if not hasattr(self.parent, 'pmworker') or self.parent.pmworker is None:
++                self.parent.pmworker = PmWorker(self.parent)
++
++            self.parent.pmworker.start_back_upgrade(pkg_list, sender)
++
++            return self.RETURN_SUCCESS_CODE, self.RETURN_SUCCESS_DESC
++        except Exception as e:
++            logging.error(str(e))
++            return self.RETURN_UNKNOWN_CODE, str(e)
++
++    @dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='asss', out_signature='is', sender_keyword='sender')
++    def PurgePackages(self, _purge_list, cur_user, user_lang = '', sender=None):
++        try:
++            sender_name = self.dbus_control.check_sender(sender)
++            purge_list = [str(pkg) for pkg in _purge_list]
++
++            if self.now_working != self.ACTION_DEFUALT_STATUS:
++                logging.warning('Updater In the process of Upgrading, ignore \'%s\' PurgePackages(%s) request ...', \
++                                sender_name, purge_list)
++                return self.RETURN_BUSY_STATE,self.RETURN_BUSY_DESC
++
++            logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' PurgePackages Sender:%s and purge list is:%s...',sender_name, purge_list)
++
++            if not hasattr(self.parent, 'pmworker') or self.parent.pmworker is None:
++                self.parent.pmworker = PmWorker(self.parent)
++
++            self.parent.pmworker.start_purge_pkgs(purge_list, sender)
++            return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
++        except Exception as e:
++            logging.error(str(e))
++            return self.RETURN_UNKNOWN_CODE,str(e)
++
++    @dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='ss',out_signature='i',sender_keyword='sender')
++    def PackageInstallStatus(self, name, version, sender=None):
++        try:
++            sender_name = self.dbus_control.check_sender(sender)
++            logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' PackageInstallStatus, name:%s, version:%s, sender:%s .',
++                        name, version, sender_name)
++
++            return self.parent.check_package_status(name, version, sender)
++        except Exception as e:
++            logging.error("PackageInstallStatus err:%s", e)
++            return -100
++
++    @dbus.service.method(UPDATER_DBUS_INTERFACE,out_signature='b',sender_keyword='sender')
++    def GetAutocheckStatus(self,sender=None):
++        sender_name = self.dbus_control.check_sender(sender)
++        logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' GetAutocheckStatus sender: %s .', sender_name)
++
++        autocheckStatus = True
++
++        try:
++            autocheckStatus = self.parent.sqlite3_server.select_from_display("auto_check")
++            logging.info("[auto_check] value is %s.", autocheckStatus)
++        except Exception as e:
++            logging.error("GetAutocheckStatus: %s.", str(e))
++
++        return autocheckStatus
++
++    #卸载完成的信号
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bss')
++    def PurgePackagesFinished(self, success,error_string='',error_desc=''):
++        logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " PurgePackagesFinished success = %r , error_string = %s , error_desc = %s ",\
++                    success,error_string,error_desc)
++
++    #卸载进度信息 0~100 进度信息 101为非预期的信号
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='iss')
++    def PurgePkgStatusChanged(self,progress,status,current_details):
++        logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" PurgePkgStatusChanged progress = %d , status = %s ,current_details = %s",\
++            progress,status,current_details)
++    
++    #卸载完成的信号,包含当前正在卸载的包名
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bsss')
++    def PurgePackagesFinishedWithPkgname(self, success,error_string='',error_desc='',current_pkg=''):
++        logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " PurgePackagesFinishedWithPkgname success = %r , error_string = %s , error_desc = %s , current purge package = %s" ,\
++                    success,error_string,error_desc,current_pkg)
++    
++    #卸载完成的信号
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bssss')
++    def PurgePackagesFinishedWithErrCode(self, success,error_string='',error_desc='',current_pkg='',error_code=''):
++        logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " PurgePackagesFinishedWithErrCode success = %r , error_string = %s , error_desc = %s , current purge package = %s , error_code = %s",\
++                    success,error_string,error_desc,current_pkg,error_code)
++
++    #卸载进度信息 0~100 进度信息 101为非预期的信号,包含当前正在卸载的包名
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='isss')
++    def PurgePkgStatusChangedWithPkgname(self,progress,status,current_details,current_pkg=''):
++        logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" PurgePkgStatusChangedWithPkgname progress = %d , status = %s ,current_details = %s, current purge package = %s",\
++            progress,status,current_details,current_pkg)
++
++    #安装deb包完成的信号
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bss')
++    def InstalldebFinished(self, success,error_string='',error_desc=''):
++        logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " InstalldebFinished success = %r , error_string = %s , error_desc = %s ",\
++                    success,error_string,error_desc)
++
++    #安装deb包完成的信号
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bsss')
++    def InstalldebFinishedWithErrCode(self, success,error_string='',error_desc='',error_code=''):
++        logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " InstalldebFinishedWithErrCode success = %r , error_string = %s , error_desc = %s , error_code = %s",\
++                    success,error_string,error_desc,error_code)
++        
++    #安装进度信息 0~100 进度信息 101为非预期的信号
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='iss')
++    def InstalldebStatusChanged(self,progress,status,current_details):
++        logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" InstalldebStatusChanged progress = %d , status = %s ,current_details = %s",\
++            progress,status,current_details)
++
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='is')
++    def EnvBuildStatusChanged(self, progress, status):
++        logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" EnvBuildStatusChanged progress = %d , status = %s",\
++            progress,status)
++
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='bs')
++    def EnvBuildStatusFinished(self, progress, status):
++        logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" EnvBuildStatusFinished progress = %d , status = %s",\
++            progress,status)
++
+     #限速修改信号
+     @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='ss')
+     def ButtonStatusChange(self, signal_types = '', value=''):
+@@ -492,6 +662,10 @@ class UpgradeStrategiesDbusController(dbus.service.Object):
+     def ButtonStatusChange(self, signal_types = '', value=''):
+         logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " ButtonStatusChange signal_types = %s, value = %s.",signal_types, value)
+ 
++    @dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='basss')
++    def UpdateInstallFinished(self, success, upgrade_group, error_string='', error_desc=''):
++        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)
+ 
+     # signal:属性发生改变
+     @dbus.service.signal(dbus_interface=UPDATER_DBUS_INTERFACE,
+diff --git a/backend-immutable/SystemUpdater/backend/BackendOstreeNext.py b/backend-immutable/SystemUpdater/backend/BackendOstreeNext.py
+index 3d03c40..52f363b 100644
+--- a/backend-immutable/SystemUpdater/backend/BackendOstreeNext.py
++++ b/backend-immutable/SystemUpdater/backend/BackendOstreeNext.py
+@@ -7,10 +7,13 @@ gi.require_version('OSTree', '1.0')
+ from gi.repository import GLib, Gio, OSTree,GObject
+ from SystemUpdater.Core.errors import *
+ from SystemUpdater.Core.enums import *
++from SystemUpdater.constants import OFFLINE_REPO_POST,DEFAULT_OS_NAME
+ from gettext import gettext as _
++from SystemUpdater.Core.diskManager import check_free_space
++from SystemUpdater.pluginbase import PluginBase
+ 
+ RETRY_LIMIT = 5
+-ORIGIN_REMOTE_NAME = "openkylin"
++DEFAULT_REPO_NAME = "kylin"
+ 
+ class BackendBaseOstree(GObject.GObject):    
+     __gsignals__ = {
+@@ -21,13 +24,13 @@ class BackendBaseOstree(GObject.GObject):
+                                 GObject.TYPE_NONE,
+                                 (   GObject.TYPE_INT,
+                                     GObject.TYPE_INT,
+-                                    GObject.TYPE_INT64,
+-                                    GObject.TYPE_INT64,
+-                                    GObject.TYPE_INT64
++                                    GObject.TYPE_ULONG,
++                                    GObject.TYPE_ULONG,
++                                    GObject.TYPE_ULONG
+                                 ))
+                     }
+     
+-    def __init__(self,parent,sysroot_path=None,osname=None):
++    def __init__(self,parent,sysroot_path=None,osname=DEFAULT_OS_NAME):
+         GObject.GObject.__init__(self)
+         self._async_progress = None
+         self.error_code = ''
+@@ -44,19 +47,18 @@ class BackendBaseOstree(GObject.GObject):
+         if booted_deployment:
+             self.osname = booted_deployment.get_osname()
+         else:
++            logging.warning("Booted deployment is None and use to defalut os name(%s)...",osname)
+             self.osname = osname
+ 
+-        self.merge_deployment = self.sysroot.get_merge_deployment(self.osname)
+-        if not self.merge_deployment:
+-            pass
+-        self.origin = self.merge_deployment.get_origin()
++        self.cur_deployment = self.sysroot.get_merge_deployment(self.osname)
++        self.origin = self.cur_deployment.get_origin()
+ 
+-        # 异常情况下origin文件origin_remote为空 默认强制openkylin
+-        refspec = self.origin.get_string("origin","refspec")
+-        ret,origin_remote,origin_ref = OSTree.parse_refspec(refspec)
+-        if origin_remote == None:
+-            origin_refspec = ORIGIN_REMOTE_NAME+":"+origin_ref
+-            self.origin.set_string("origin","refspec",origin_refspec)
++        # 加载插件机制
++        # 获取当前运行程序的插件目录位置
++        # self.plugins_dir = os.path.join(os.getcwd(),"SystemUpdater/plugins")
++        # # 基础插件 所有插件的位置
++        # test = os.path.join(self.plugins_dir,"base")
++        # self.plugin_base = PluginBase(package='SystemUpdater.plugins',searchpath=[os.path.join(self.plugins_dir,"base")])
+ 
+     def run(self,trans=None):
+         logging.info("Processing transaction")
+@@ -137,74 +139,151 @@ class BackendBaseOstree(GObject.GObject):
+             logging.error(str(tbk))
+ 
+     def _make_error(self,error,trans):
+-        if error.code in (0,37):
+-            self.error_code = ERROR_NETWORK_FAILED
+-        #取消
+-        elif error.code == 19:
+-            trans.cancellable.reset()
+-            self.error_code = ERROR_CANCELLED
+-        elif error.code == 1:
+-            #Remote "kylin" not found (1)
+-            self.exit = True
++        if trans.role == ROLE_DEPLOY_ONLY:
++            self.error_code = get_error_num_from_enum(ERROR_NOT_DEPLOYMENT)
++        else:
++            if error.code in (0,37):
++                self.error_code = get_error_num_from_enum(ERROR_NETWORK_FAILED)
++            #取消
++            elif error.code == 19:
++                trans.cancellable.reset()
++                self.error_code = get_error_num_from_enum(EXIT_CANCELLED)
++            elif error.code == 1:
++                # 在远程分支 未找到 对应的 分支 
++                if "Server returned status 404" in error.message:
++                    self.error_code = get_error_num_from_enum(ERROR_PUSH_BRANCH_EXCEPTION)
++                # 未找到 对应的仓库信息 
++                elif "Remote" in error.message and "not found" in error.message:
++                    self.exit = True
++    
++    def _open_offline_repo(self):
++        # 检查是否存在离线仓库
++        offline_flag = OFFLINE_REPO_POST + "/config"
++        if os.path.exists(offline_flag):
++            g_file= Gio.File.new_for_path(OFFLINE_REPO_POST)
++            offline_repo = OSTree.Repo.new(g_file)
++            ret = offline_repo.open()
++            return offline_repo
++        else:
++            return None
+ 
+-class UpdateBackend(BackendBaseOstree):
++    def register_formatter(self, name, formatter):
++        """A function a plugin can use to register a formatter."""
++        self.formatters[name] = formatter
++
++    def _load_plugins(self,identifier):
++        # 每次formatters将被刷新
++        self.formatters = {}
++        plugin_dir = os.path.join(self.plugins_dir,identifier)
++        plugins_sources = self.plugin_base.make_plugin_source(searchpath=[plugin_dir],identifier=identifier)
++
++        # 初始化插件
++        for plugin_name in plugins_sources.list_plugins():
++            plugin = plugins_sources.load_plugin(plugin_name)
++            plugin.setup(self)
++        return self.formatters
+ 
++class UpdateBackend(BackendBaseOstree):
+     def __init__(self,parent,sysroot_path=None,osname=None):
+         """Initialize a new AptWorker instance."""
+         BackendBaseOstree.__init__(self,parent,sysroot_path,osname)
++        
++        #更新前插件
++        # self.update_formatters = self._load_plugins("update")
+ 
+     def _run_transaction(self, sysroot,trans):
++        g_options = { 
++                        "n-network-retries":GLib.Variant("u",RETRY_LIMIT),\
++                        "flags":GLib.Variant("i",OSTree.RepoPullFlags.COMMIT_ONLY),\
++                        # "timestamp-check":GLib.Variant("b",True),\
++                        "depth":GLib.Variant("i",1)
++                    }
++        push_revision = None
+         ostree_repo = sysroot.repo()
+-        from_revision = self.merge_deployment.get_csum()
+-        
+-        refspec = self.origin.get_string("origin","refspec")
+-        ret,origin_remote,origin_ref = OSTree.parse_refspec(refspec)
+-
+-        g_options = GLib.Variant("a{sv}",
+-                                {   "refs":GLib.Variant("as",[origin_ref]),\
+-                                    "n-network-retries":GLib.Variant("u",RETRY_LIMIT),\
+-                                    "flags":GLib.Variant("i",OSTree.RepoPullFlags.COMMIT_ONLY),\
+-                                    # "timestamp-check":GLib.Variant("b",True),\
+-                                    "depth":GLib.Variant("i",1)
+-                                })
+-        
+-        logging.info("Start pull metadata refs:%s...",origin_ref)
+-        ret = ostree_repo.pull_with_options(origin_remote,g_options,self._async_progress,trans.cancellable)
+ 
+-        origin_refspec = origin_remote+":"+origin_ref
+-        ret,new_revision = ostree_repo.resolve_rev(origin_refspec,True)
+-        new_ref = origin_ref
++        # 获取当前部署分支的checksum与当前部署的分支
++        from_revision = self.cur_deployment.get_csum()
++        refspec = self.origin.get_string("origin","refspec")
++        ret,remote_repo,deployed_refs = OSTree.parse_refspec(refspec)
++        if not remote_repo:
++            logging.error("Now system deployment repo name is None...")
++            raise UpdateBaseError(ERROR_REPO_IS_NONE)
++
++        logging.info("Now system deployment info(%s:%s@%s)...",remote_repo,deployed_refs,from_revision)
++
++        # 加载推送更新 当推送为空时 直接去服务端 拉取当前分支最新的commit
++        if trans.push_list:
++            for push in trans.push_list:
++                remote_repo = push.repo_name
++                pull_ref = push.branch
++                # 指定拉取的commit id,不指定时拉取当前分支最新的
++                if push.revision:
++                    g_options["override-commit-ids"] = GLib.Variant("as",[push.revision])
++                    push_revision = push.revision
++                break
++        else:
++        # 未推送情况下 获取当前部署的分支
++            pull_ref = deployed_refs
++                
++        g_options["refs"] = GLib.Variant("as",[pull_ref])
++        logging.info("Start pull metadata and options:%s...",g_options)
++        ostree_repo.pull_with_options(remote_repo,GLib.Variant("a{sv}",g_options),self._async_progress,trans.cancellable)
++
++        # 没有指定commit情况下 检索当前分支最新commit
++        if not push_revision:
++            ret,new_revision = ostree_repo.resolve_rev(remote_repo+":"+pull_ref,True)
++        else:
++            new_revision = push_revision
+ 
+         ret,metadata = ostree_repo.load_variant(OSTree.ObjectType.COMMIT,new_revision)
+         
+         n_metadata = metadata[0]
+ 
+         # 检查是否当前分支已经终止,切换到新的分支
+-        if OSTree.COMMIT_META_KEY_ENDOFLIFE_REBASE in n_metadata:
+-            new_ref = n_metadata[OSTree.COMMIT_META_KEY_ENDOFLIFE_REBASE]
++        if OSTree.COMMIT_META_KEY_ENDOFLIFE_REBASE in n_metadata and not trans.push_list:
+             # 拉取新分支的元数据
+-            g_options = GLib.Variant("a{sv}",
+-                                    {   "refs":GLib.Variant("as",[new_ref]),\
+-                                        "n-network-retries":GLib.Variant("u",RETRY_LIMIT),\
+-                                        "flags":GLib.Variant("i",OSTree.RepoPullFlags.COMMIT_ONLY),\
+-                                        # "timestamp-check":GLib.Variant("b",True),\
+-                                        "depth":GLib.Variant("i",1)
+-                                    })
+-            logging.info("From origin ref:%s To new refs:%s...",origin_ref,new_ref)
+-            logging.info("Start pull new metadata refs:%s...",new_ref)
+-            ret = ostree_repo.pull_with_options(origin_remote,g_options,self._async_progress,trans.cancellable)
+-
+-            origin_refspec = origin_remote+":"+new_ref
+-            ret,new_revision = ostree_repo.resolve_rev(origin_refspec,True)
++            new_ref = n_metadata[OSTree.COMMIT_META_KEY_ENDOFLIFE_REBASE]
++            logging.info("From origin ref:%s To new refs:%s...",pull_ref,new_ref)
+ 
+-        ret,metadata = ostree_repo.load_variant(OSTree.ObjectType.COMMIT,new_revision) 
+-        
+-        # 判断是否有新的更新
++            pull_ref = new_ref
++            logging.info("Start pull new metadata refs:%s...",pull_ref)
++            g_options["refs"] = GLib.Variant("as",[pull_ref])
++            ret = ostree_repo.pull_with_options(remote_repo,GLib.Variant("a{sv}",g_options),self._async_progress,trans.cancellable)
++            
++            ret,new_revision = ostree_repo.resolve_rev(remote_repo+":"+pull_ref,True)
++            
++        ret,metadata = ostree_repo.load_variant(OSTree.ObjectType.COMMIT,new_revision)
++
++        logging.info("new_revision:%s and all metadata:%s...",new_revision,metadata[0])        
++
++        trans.available_metadata = metadata[0]
+         trans.from_revision = from_revision
++        trans.available_repo = remote_repo
+         trans.new_revision = new_revision
+-        trans.available_refs = new_ref
++        trans.available_refs = pull_ref
++        trans.deployed_refs = deployed_refs
++
++    def _get_commit_recursive(self,ostree_repo,checksum):
++        # 如果 start 不在 all_deltas 中,返回空列表
++        ret,metadata = ostree_repo.load_variant(OSTree.ObjectType.COMMIT,checksum)
++        if not metadata:
++            return []
++        parent = OSTree.commit_get_parent(metadata)
++        if parent:
++            return [parent] + self._get_commit_recursive(ostree_repo, parent)
++        else:
++            return []
+ 
+-        trans.available_metadata = metadata[0]
++    def _get_all_commit(self,ostree_repo):
++        commit_and_refs = {}
++        ret,out_all_refs = ostree_repo.list_refs(None,None)
++        
++        for refs in out_all_refs:
++            commit_list = self._get_commit_recursive(ostree_repo,out_all_refs[refs])
++            for commit in commit_list:
++                commit_and_refs[commit] = refs
++
++        logging.info(commit_and_refs)
+ 
+ class DownloadBackend(BackendBaseOstree):
+     def __init__(self,parent,sysroot_path=None,osname=None):
+@@ -212,29 +291,65 @@ class DownloadBackend(BackendBaseOstree):
+         BackendBaseOstree.__init__(self,parent,sysroot_path,osname)
+         self.download_size = 0
+ 
++        self.g_options = {
++                            "n-network-retries":GLib.Variant("u",RETRY_LIMIT),\
++                            # "timestamp-check":GLib.Variant("b",True),\
++                            # "low-speed-limit-bytes":GLib.Variant("u",10),\
++                            # "low-speed-limit-seconds":GLib.Variant("u",20),\
++                            "flags":GLib.Variant("i",OSTree.RepoPullFlags.NONE),\
++                            "depth":GLib.Variant("i",1)
++                        }
++
++    def _get_offline_deltas(self):
++        all_deltas = []
++        offline_repo = self._open_offline_repo()
++        if offline_repo:
++            all_deltas = {}
++            ret,deltas_list = offline_repo.list_static_delta_names(None)
++            logging.info("Offline Repo(%s) has delta files:%r",OFFLINE_REPO_POST,deltas_list)
++            for delta in deltas_list:
++                from_rev = delta.split("-")[0]
++                to_rev = delta.split("-")[1]
++                all_deltas[from_rev] = to_rev
++
++        return all_deltas
++
+     def _run_transaction(self, sysroot,trans):
+         ostree_repo = sysroot.repo()
+-        refspec = self.origin.get_string("origin","refspec")
+-        ret,origin_remote,origin_ref = OSTree.parse_refspec(refspec)
++        
++        remote_repo = trans.available_repo
+         if trans.available_metadata:
+-            self.download_size = int(trans.available_metadata.setdefault("ostree.incrementsize",0))
+-
+-        logging.info("start pull data from available_refs:%s...",trans.available_refs)
+-        g_options = GLib.Variant("a{sv}",
+-                                 {
+-                                    "refs":GLib.Variant("as",[trans.available_refs]),\
+-                                    "n-network-retries":GLib.Variant("u",RETRY_LIMIT),\
+-                                    # "timestamp-check":GLib.Variant("b",True),\
+-                                    # "low-speed-limit-bytes":GLib.Variant("u",10),\
+-                                    # "low-speed-limit-seconds":GLib.Variant("u",20),\
+-                                    "flags":GLib.Variant("i",OSTree.RepoPullFlags.NONE),\
+-                                    "depth":GLib.Variant("i",1)
+-                                })
+-
+-        ostree_repo.pull_with_options(origin_remote,g_options,self._async_progress,trans.cancellable)
++            self.download_size = int(trans.dowanload_size)
++
++        check_free_space(self.download_size)
++
++        self.g_options["refs"] = GLib.Variant("as",[trans.available_refs])
++
++        all_deltas = self._get_offline_deltas()
++        if all_deltas:
++            pull_deltas = self._get_deltas_recursive(trans.from_revision,all_deltas)
++            self.g_options["require-static-deltas"] = GLib.Variant("b",True)
++
++            # 循环拉取所有的 deltas
++            for delta in pull_deltas:
++                self.g_options["override-commit-ids"] = GLib.Variant("as",[delta])
++                logging.info("Start pull data and options:%s...",self.g_options)
++                ostree_repo.pull_with_options(remote_repo,GLib.Variant("a{sv}",self.g_options),self._async_progress,trans.cancellable)
++        else:
++            self.g_options["override-commit-ids"] = GLib.Variant("as",[trans.new_revision])
++            logging.info("Start pull data and options:%s...",self.g_options)
++            ostree_repo.pull_with_options(remote_repo,GLib.Variant("a{sv}",self.g_options),self._async_progress,trans.cancellable)
+ 
+         # 下载完成后检查下载的元数据的时间戳
+         # upgrader.check_timestamps(ostree_repo,from_revision,trans.new_revision)
++    
++    def _get_deltas_recursive(self,start, all_deltas):
++        # 如果 start 不在 all_deltas 中,返回空列表
++        if start not in all_deltas:
++            return []
++        # 获取下一个值并递归处理
++        next_value = all_deltas[start]
++        return [next_value] + self._get_deltas_recursive(next_value, all_deltas)
+ 
+     def _on_async_progress(self,obj):
+         try:
+@@ -287,11 +402,10 @@ class DeployBackend(BackendBaseOstree):
+         refs = trans.available_refs
+ 
+         # 获取当前origin文件
+-        refspec = self.origin.get_string("origin","refspec")
+-        ret,origin_remote,origin_ref = OSTree.parse_refspec(refspec)
++        remote_repo = trans.available_repo
+ 
+         # 修改origin 为当前部署新分支
+-        origin_refspec = origin_remote+":"+refs
++        origin_refspec = remote_repo+":"+refs
+         # 创建新的origin文件
+         deploy_origin = sysroot.origin_new_from_refspec(origin_refspec)
+ 
+@@ -306,12 +420,12 @@ class DeployBackend(BackendBaseOstree):
+ 
+         self._progress_to_plymouth(60)
+         
+-        logging.info("start deploy available_refs:%s new_revision:%s...",refs,new_revision)
+-        ret,upgrade_deployment = sysroot.deploy_tree(self.osname,new_revision,deploy_origin,self.merge_deployment,None,None)
++        logging.info("Start deploy and available_refs:%s new_revision:%s...",refs,new_revision)
++        ret,upgrade_deployment = sysroot.deploy_tree(self.osname,new_revision,deploy_origin,self.cur_deployment,None,None)
+ 
+         # 进行部署时 保留历史部署
+         flags = OSTree.SysrootSimpleWriteDeploymentFlags.RETAIN
+-        sysroot.simple_write_deployment(self.osname,upgrade_deployment,self.merge_deployment,flags,None)
++        sysroot.simple_write_deployment(self.osname,upgrade_deployment,self.cur_deployment,flags,None)
+ 
+         self._progress_to_plymouth(90)
+ 
+@@ -402,7 +516,7 @@ class RollbackBackend(BackendBaseOstree):
+ 
+         origin = out_rollback.get_origin()
+         refspec = origin.get_string("origin","refspec")
+-        ret,origin_remote,origin_ref = OSTree.parse_refspec(refspec)
++        ret,remote_repo,origin_ref = OSTree.parse_refspec(refspec)
+ 
+         trans.available_refs = origin_ref
+ 
+@@ -417,7 +531,7 @@ class LoadCacheBackend(BackendBaseOstree):
+ 
+     def _get_refs(self):
+         refspec = self.origin.get_string("origin","refspec")
+-        ret,origin_remote,origin_ref = OSTree.parse_refspec(refspec)
++        ret,remote_repo,origin_ref = OSTree.parse_refspec(refspec)
+         if origin_ref == None:
+             origin_ref = ''
+         return origin_ref
+@@ -428,7 +542,7 @@ class LoadCacheBackend(BackendBaseOstree):
+         if out_rollback and not out_rollback.is_pinned():
+             rollback_origin = out_rollback.get_origin()
+             refspec = rollback_origin.get_string("origin","refspec")
+-            ret,origin_remote,origin_ref = OSTree.parse_refspec(refspec)
++            ret,remote_repo,origin_ref = OSTree.parse_refspec(refspec)
+             
+             return [origin_ref]
+         else:
+diff --git a/backend-immutable/SystemUpdater/configs.py b/backend-immutable/SystemUpdater/configs.py
+new file mode 100644
+index 0000000..34b43fe
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/configs.py
+@@ -0,0 +1,67 @@
++import json
++import logging
++DEFAULT_SETTINGS = "/etc/kylin-system-updater/settings-default.json"
++RUN_SETTINGS = "/var/cache/kylin-system-updater/settings.json"
++class JSONConfig:
++    def __init__(self, settings_files = []):
++        self.configs = {}
++
++        # 循环读取所有的配置文件,并将配置进行合并,最后的配置文件优先级最高
++        for config_file in settings_files:
++            try:
++                with open(config_file, "r") as f:
++                    config_data = json.load(f)
++                    self.configs = {**self.configs, **config_data}  # 使用字典解包进行合并
++            except Exception as e:
++                pass
++
++        self.settings_files = settings_files
++
++    def get(self, key, default=None):
++        return self.configs.get(key, default)
++
++    def set(self, key, value):
++        self.configs[key] = value
++
++    def __getitem__(self, key):
++        return self.configs[key]
++
++    def __setitem__(self, key, value):
++        logging.info(f"Settings: setting '{key}' to '{value}'")
++        self.configs[key] = value
++
++    def update(self, new_data):
++        if isinstance(new_data, dict):
++            self.configs.update(new_data)
++        else:
++            raise TypeError("update() expects a dictionary")
++        
++    def save(self):
++        with open(self.settings_files[-1], 'w') as f:
++            json.dump(self.configs, f, indent=4)
++
++"""
++ 使用方式:
++    获取值
++    1、settings.get("name")  == "Bob"
++    2、settings.get("name1", "default") == "default"
++    3、settings.get("local",{}).get("pre",{}).get("en") == "xxxxx"
++
++    设置值
++    1、settings.set("name", "Bob")
++    # 仅支持一级设置
++    2、settings["name"] = "Bob"
++    3、支持多级设置
++        a、locals = settings.get("local",{})
++        b、locals["pre"]["en"] = "xxxxx"
++
++    保存
++    settings.save()
++"""
++
++settings = JSONConfig(
++    settings_files=[
++        DEFAULT_SETTINGS,
++        RUN_SETTINGS,
++    ]
++)
+\ No newline at end of file
+diff --git a/backend-immutable/SystemUpdater/constants.py b/backend-immutable/SystemUpdater/constants.py
+new file mode 100644
+index 0000000..fcb227f
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/constants.py
+@@ -0,0 +1,12 @@
++
++PUTSH_CONTENT_LOCATION = "/opt/kylin-software-properties/ostree-important.list"
++
++OFFLINE_REPO_POST = "/tmp/ostree-auto-test/offline-repo"
++
++OUTPUT_JSON_PATH = '/var/cache/kylin-system-updater/json/'
++
++SYSTEM_UPDATE_GROUPS = "kylin-update-desktop-system"
++
++DEFAULT_OS_NAME = "kylin"
++
++DEFAULT_REPO_NAME = "kylin"
+\ No newline at end of file
+diff --git a/backend-immutable/SystemUpdater/packageManager/UpdaterSDKInterface.py b/backend-immutable/SystemUpdater/packageManager/UpdaterSDKInterface.py
+new file mode 100644
+index 0000000..8bbf813
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/packageManager/UpdaterSDKInterface.py
+@@ -0,0 +1,584 @@
++import os
++import ctypes
++import logging
++import subprocess
++
++from enum import Enum
++from SystemUpdater.packageManager.pmUtils import *
++
++class KSettingsPrivate(ctypes.Structure):
++    GMainContext = ctypes.c_void_p
++    KSettingsSchema = ctypes.c_void_p
++    GDBusConnection = ctypes.c_void_p
++
++    _fields_ = [
++        ("main_context", ctypes.POINTER(GMainContext)),
++        ("schema", ctypes.POINTER(KSettingsSchema)),
++        ("conn", ctypes.POINTER(GDBusConnection)),
++        ("sub_id", ctypes.c_uint * 2)
++    ]
++
++class KSettings(ctypes.Structure):
++    _fields_ = [
++        ("parent_instance", ctypes.c_void_p),   # GObject parent_instance
++        ("priv", ctypes.POINTER(KSettingsPrivate))
++    ]
++
++class UpdaterSDKInterface:
++    def __init__(self, libraryPath = '', archRelatedLib = ''):
++
++        self.sdkLib     = None
++        self.sdkLoaded  = False
++
++        try:
++            if archRelatedLib:
++                libraryPath = self.arch_related_library_path(archRelatedLib)
++
++            if os.path.exists(libraryPath):
++                self.sdkLib     = ctypes.cdll.LoadLibrary(libraryPath)
++                self.sdkLoaded  = True
++            else:
++                logging.warning("%s dose not exist.", libraryPath)
++        except Exception as e:
++            logging.error("UpdaterSDKInterface init error: %s", e)
++
++    def arch_related_library_path(self, archRelatedLib):
++        archRelatedLibPath = ''
++
++        try:
++            multiarch = subprocess.check_output(['dpkg-architecture', '-qDEB_HOST_MULTIARCH'], timeout=3).decode().strip()
++            archRelatedLibPath = os.path.join("/usr/lib", multiarch, archRelatedLib)
++        except Exception as e:
++            logging.error("arch_related_library_path error: %s", e)
++
++        return archRelatedLibPath
++
++    def function_exists(self, funcName):
++        try:
++            getattr(self.sdkLib, funcName)
++            return True
++        except AttributeError:
++            return False
++
++
++class UpdaterSDKConf2:
++    KCONF2_LIBRARY   = 'libkyconf2.so'
++    APPLICATION_NAME = 'kylin-update-frontend'
++    GROUP_TO_LISTEN  = [
++        'kylin-update-frontend.notification',
++        'kylin-update-frontend.downloadlimit',
++        'kylin-update-frontend.autodownload',
++        'kylin-update-frontend.autobackup',
++        'kylin-update-frontend.downloadsettings'
++        ]
++    GROUP_SETTINGS   = {}
++
++    def __init__(self, parent = None):
++        self.conf2Loaded      = False
++        self.strategieService = parent
++        self.sdkInterface     = UpdaterSDKInterface(archRelatedLib = self.KCONF2_LIBRARY)
++
++        if not self.sdkInterface.sdkLoaded:
++            logging.warning("'%s' load error", self.KCONF2_LIBRARY)
++        else:
++            self.conf2_interface_init()
++
++    def conf2_interface_init(self):
++        try:
++            if self.sdkInterface.function_exists("kdk_conf2_new"):
++                self.sdkInterface.sdkLib.kdk_conf2_new.argtypes  = [ctypes.c_char_p, ctypes.c_char_p]
++                self.sdkInterface.sdkLib.kdk_conf2_new.restype   = ctypes.POINTER(KSettings)
++
++                for gtl in self.GROUP_TO_LISTEN:
++                    self.GROUP_SETTINGS.update({gtl:self.sdkInterface.sdkLib.kdk_conf2_new(gtl.encode('utf-8'), None)})
++
++            else:
++                logging.warning("kdk_conf2_new do not find in '%s'", self.KCONF2_LIBRARY)
++                self.conf2Loaded = False
++                return
++
++            if self.sdkInterface.function_exists("kdk_conf2_get_string"):
++                self.sdkInterface.sdkLib.kdk_conf2_get_string.argtypes = [ ctypes.POINTER(KSettings),
++                                                                         ctypes.c_char_p]
++                self.sdkInterface.sdkLib.kdk_conf2_get_string.restype  = ctypes.c_char_p
++            else:
++                self.conf2Loaded = False
++                return
++
++            if self.sdkInterface.function_exists("kdk_conf2_set_value"):
++                self.sdkInterface.sdkLib.kdk_conf2_set_value.argtypes = [ ctypes.POINTER(KSettings),
++                                                                        ctypes.c_char_p,
++                                                                        ctypes.c_char_p]
++                self.sdkInterface.sdkLib.kdk_conf2_set_value.restype  = ctypes.c_int
++            else:
++                self.conf2Loaded = False
++                return
++
++            if self.sdkInterface.function_exists("kdk_conf2_ksettings_destroy"):
++                pass
++            else:
++                self.conf2Loaded = False
++                return
++
++
++            # TODO: ctypes使用kdk_conf2_connect_signal时回调无法触发...
++            # KCallBack = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p)
++
++            # @KCallBack
++            # def on_key_changed(setting, key, user_data):
++            #     key_str = key.decode('utf-8')
++            #     logging.info("'%s' change detected", key_str)
++
++            # self.sdkInterface.sdkLib.kdk_conf2_connect_signal.argtypes = [ ctypes.POINTER(KSettings),
++            #                                                   ctypes.c_char_p,
++            #                                                   KCallBack,
++            #                                                   ctypes.c_void_p]
++            # self.sdkInterface.sdkLib.kdk_conf2_connect_signal.restype  = ctypes.c_ulong
++            # self.sdkInterface.sdkLib.kdk_conf2_connect_signal(ksettings_ptr, b"changed", on_key_changed, None)
++
++            self.conf2_listen_key_changed()
++
++            self.conf2Loaded = True
++        except Exception as e:
++            logging.error("conf2_interface_init error: %s", e)
++
++    def conf2_listen_key_changed(self):
++        try:
++            def conf2_key_changed_handler(schema, version, key):
++                if schema in self.GROUP_TO_LISTEN:
++                    changed_value = self.conf2_get_key_value(schema, key).decode('utf-8')
++
++                    logging.info("key_changed signal: %s(%s):%s -> %s",
++                                 schema, version, key, changed_value)
++
++                    if schema == 'kylin-update-frontend.notification':
++
++                        if "enable" == key:
++                            self.strategieService.dbus_send.AutocheckStatusChanged(
++                                                True if str(changed_value).lower() == 'true' else False)
++
++                    elif schema == 'kylin-update-frontend.downloadlimit':
++
++                        if "enable" == key:
++                            downloadlimitValue = self.conf2_get_key_value(schema, 'value')
++                            self.strategieService.dbus_send.DownloadStatusChanged(
++                                                True if str(changed_value).lower() == 'true' else False,
++                                                int(downloadlimitValue))
++                        
++                        elif "value" == key:
++                            downloadspeedLimitStatus = self.conf2_get_key_value(schema, 'enable')
++                            self.strategieService.dbus_send.DownloadStatusChanged(
++                                                True if downloadspeedLimitStatus.lower() == 'true' else False,
++                                                int(str(changed_value)) if str(changed_value).isdigit() else int(0))
++
++                    elif schema == 'kylin-update-frontend.autodownload':
++
++                        if "enable" == key:
++                            self.strategieService.dbus_send.AutoUpgradeStatusChanged(
++                                                True if str(changed_value).lower() == 'true' else False)
++            
++            # conf2_service_proxy = self.strategieService.bus.get_object('com.kylin.kysdk.conf2',
++            #                                                            '/com/kylin/kysdk/conf2',
++            #                                                            follow_name_owner_changes=True)
++            # conf2_service_proxy.connect_to_signal("key_changed", conf2_key_changed_handler)   
++            self.strategieService.bus.add_signal_receiver(
++                                            conf2_key_changed_handler,
++                                            dbus_interface='com.kylin.kysdk.conf2',
++                                            signal_name='key_changed'
++                                        )
++
++        except Exception as e:
++            logging.error("conf2_listen_key_changed error: %s", e)
++
++    def conf2_get_key_value(self, schema, key):
++        updater_kconf2_value = ''
++
++        try:
++            updater_kconf2_value = self.sdkInterface.sdkLib.kdk_conf2_get_string(
++                                                                self.GROUP_SETTINGS[schema],
++                                                                key.encode('utf-8'))
++
++            logging.info("conf2_get_key_value: %s:%s -> %s.", schema, key, updater_kconf2_value)
++        except Exception as e:
++            logging.error("conf2_get_key_value: %s",str(e))
++
++        return updater_kconf2_value
++
++    def conf2_set_key_value(self, schema, key, updater_kconf2_value):
++        setStatus = True
++        try:
++            setStatus = self.sdkInterface.sdkLib.kdk_conf2_set_value(
++                                                            self.GROUP_SETTINGS[schema],
++                                                            key.encode('utf-8'),
++                                                            updater_kconf2_value.encode('utf-8'))
++            setStatus = True if setStatus == int(0) else False
++            logging.info("conf2_set_key_value: %s:%s -> %s.", schema, key, updater_kconf2_value)
++        except Exception as e:
++            logging.error("conf2_set_key_value: %s",str(e))
++            setStatus = False
++
++        return setStatus
++
++    def quitKConf2Manager(self):
++        pass
++
++class InstallMode(Enum):
++    KDK_PACKAGE_AUTO    = 0
++    KDK_PACKAGE_KARE    = 1
++    KDK_PACKAGE_KAIMING = 2
++    KDK_PACKAGE_DEBIAN  = 3
++
++
++class UpdaterSDKPkgInstall:
++    SDK_LIBRARY = 'libkypackage.so'
++    KCallBack   = ctypes.CFUNCTYPE(None, ctypes.c_int, ctypes.c_int, ctypes.c_char_p)
++
++    KDK_PACKAGE_INSTALL_ERROR       =  0
++    KDK_PACKAGE_INSTALL_SUCCESS     =  1
++
++    def __init__(self, parent = None):
++        self.installLoaded    = False
++        self.upgradeService   = parent
++        self.sdkInterface     = UpdaterSDKInterface(archRelatedLib = self.SDK_LIBRARY)
++
++        if not self.sdkInterface.sdkLoaded:
++            logging.warning("'%s' load error", self.SDK_LIBRARY)
++        else:
++            self.package_interface_init()
++
++        self.purge_status_changed           = self.KCallBack(self._purge_callback_wrapper)
++        self.install_status_changed         = self.KCallBack(self._install_callback_wrapper)
++        self.batch_install_status_changed   = self.KCallBack(self._batch_install_callback_wrapper)
++
++        self.purgeFinished      = False
++        self.installFinished    = False
++        self.batchInstFinished  = False
++
++        self.progress_restore   = 0
++        self.batchInstPkgs      = []
++        self.batchInstPkgsNum   = 0
++        self.batchInstPkgsIndex = 0
++
++    # state状态
++    # 0: 卸载成功
++    # 1: 正在卸载包
++    # other: 错误
++    def _purge_callback_wrapper(self, progress, state, loginfo):
++        try:
++            _loginfo = loginfo.decode("utf-8")
++            # logging.info("purge_status_changed, progress: %d, state: %d, loginfo: %s.", progress, state, _loginfo)
++
++            if state == 0:
++                if progress == 100:
++                    self.purgeFinished = True
++                    self.upgradeService.dbus_send.PurgePackagesFinished(True, _loginfo,'')
++                    self.upgradeService.dbus_send.PurgePackagesFinishedWithPkgname(True, _loginfo, '', '')
++                    self.upgradeService.dbus_send.PurgePackagesFinishedWithErrCode(True, _loginfo, '', '', get_error_num_from_enum(SUCCESS_PURGE_PKG))
++
++            elif state == 1:
++                if progress == 100:
++                    self.purgeFinished = True
++                    self.upgradeService.dbus_send.PurgePackagesFinished(True, _loginfo,'')
++                    self.upgradeService.dbus_send.PurgePackagesFinishedWithPkgname(True, _loginfo, '', '')
++                    self.upgradeService.dbus_send.PurgePackagesFinishedWithErrCode(True, _loginfo, '', '', get_error_num_from_enum(SUCCESS_PURGE_PKG))
++                else:
++                    self.upgradeService.dbus_send.PurgePkgStatusChanged(progress, str(state), _loginfo)
++
++            elif state < 0:
++                self.purgeFinished = True
++                self.upgradeService.dbus_send.PurgePackagesFinished(False, _loginfo,'')
++                self.upgradeService.dbus_send.PurgePackagesFinishedWithPkgname(False, _loginfo, '', '')
++                self.upgradeService.dbus_send.PurgePackagesFinishedWithErrCode(False, _loginfo, '', '', get_error_num_from_enum(ERROR_PURGE_PKG_DPKG))
++
++            else:
++                logging.info("purge_status_changed other, progress: %d, state: %d, loginfo: %s.", progress, state, _loginfo)
++
++        except Exception as e:
++            logging.error("_install_callback_wrapper error: %s", e)
++
++    # state状态
++    # 0: 安装成功
++    # 1: 正在安装包
++    # 2: 正在构建环境
++    # other: 错误
++    def _install_callback_wrapper(self, progress, state, loginfo):
++        try:
++            _loginfo = loginfo.decode("utf-8")
++            # logging.info("install_status_changed, progress: %d, state: %d, loginfo: %s.", progress, state, _loginfo)
++
++            if state == 0:
++                if progress == 100:
++                    self.installFinished = True
++                    self.upgradeService.dbus_send.InstalldebFinished (True, '', _loginfo)
++                    self.upgradeService.dbus_send.InstalldebFinishedWithErrCode (True, '', _loginfo, '')
++
++            elif state == 1:
++                if progress == 100:
++                    self.installFinished = True
++                    self.upgradeService.dbus_send.InstalldebFinished (True, '', _loginfo)
++                    self.upgradeService.dbus_send.InstalldebFinishedWithErrCode (True, '', _loginfo, '')
++                else:
++                    self.upgradeService.dbus_send.InstalldebStatusChanged(progress, str(state), _loginfo)
++
++            elif state == 2:
++                if progress == 100:
++                    self.upgradeService.dbus_send.EnvBuildStatusChanged(progress, str(_loginfo))
++                    self.upgradeService.dbus_send.EnvBuildStatusFinished(True, str(_loginfo))
++                else:
++                    self.upgradeService.dbus_send.EnvBuildStatusChanged(progress, str(_loginfo))
++
++            elif state < 0:
++                self.installFinished = True
++                self.upgradeService.dbus_send.InstalldebFinished (False, '', _loginfo)
++                self.upgradeService.dbus_send.InstalldebFinishedWithErrCode (False, '', _loginfo, '')
++
++            else:
++                logging.info("install_status_changed other, progress: %d, state: %d, loginfo: %s.", progress, state, _loginfo)
++
++        except Exception as e:
++            logging.error("_install_callback_wrapper error: %s", e)
++
++    def _batch_install_callback_wrapper(self, progress, state, loginfo):
++        try:
++            _loginfo = loginfo.decode("utf-8")
++            _progress = int((progress * 100.0 / self.batchInstPkgsNum + self.batchInstPkgsIndex * 100 * 100.0 / self.batchInstPkgsNum) / 100)
++
++            if _progress < self.progress_restore:
++                _progress = self.progress_restore
++            else:
++                self.progress_restore = _progress
++
++            logging.info("_batch_install_callback_wrapper(%d/%d[%d]), progress: %d, state: %d, loginfo: %s.", 
++                         self.batchInstPkgsIndex + 1, self.batchInstPkgsNum, _progress, progress, state, _loginfo)
++
++            if state == 0:
++                if progress == 100:
++                    if self.batchInstPkgsIndex == self.batchInstPkgsNum:
++                        self.batchInstFinished = True
++                        self.upgradeService.dbus_send.UpdateInstallFinished(True, self.batchInstPkgs, '', _loginfo)
++                    else:
++                        self.upgradeService.dbus_send.InstalldebStatusChanged(_progress, str(state), _loginfo)
++
++            elif state == 1:
++                if progress == 100:
++                    if self.batchInstPkgsIndex == self.batchInstPkgsNum:
++                        self.batchInstFinished = True
++                        self.upgradeService.dbus_send.UpdateInstallFinished(True, self.batchInstPkgs, '', _loginfo)
++                    else:
++                        self.upgradeService.dbus_send.InstalldebStatusChanged(_progress, str(state), _loginfo)
++
++                else:
++                    self.upgradeService.dbus_send.InstalldebStatusChanged(_progress, str(state), _loginfo)
++
++            elif state == 2:
++                if progress == 100:
++                    self.upgradeService.dbus_send.EnvBuildStatusChanged(progress, str(_loginfo))
++                    self.upgradeService.dbus_send.EnvBuildStatusFinished(True, str(_loginfo))
++                else:
++                    self.upgradeService.dbus_send.EnvBuildStatusChanged(progress, str(_loginfo))
++
++            elif state < 0:
++                if self.batchInstPkgsIndex == self.batchInstPkgsNum:
++                    self.batchInstFinished = True
++                    self.upgradeService.dbus_send.UpdateInstallFinished(False, self.batchInstPkgs, '', _loginfo)
++                else:
++                    self.upgradeService.dbus_send.InstalldebStatusChanged(_progress, str(state), _loginfo)
++
++            else:
++                logging.info("_batch_install_callback_wrapper other, progress: %d, state: %d, loginfo: %s.", progress, state, _loginfo)
++
++        except Exception as e:
++            logging.error("_batch_install_callback_wrapper error: %s", e)
++
++    def package_interface_init(self):
++        try:
++            if self.sdkInterface.function_exists("kdk_package_install_package"):
++                self.sdkInterface.sdkLib.kdk_package_install_package.argtypes  = [ctypes.c_char_p, ctypes.c_int, self.KCallBack]
++                self.sdkInterface.sdkLib.kdk_package_install_package.restype   = ctypes.c_int
++            else:
++                logging.warning("kdk_package_install_package do not find in '%s'", self.SDK_LIBRARY)
++                self.conf2Loaded = False
++                return
++
++            if self.sdkInterface.function_exists("kdk_package_install_package_online"):
++                self.sdkInterface.sdkLib.kdk_package_install_package_online.argtypes  = [ctypes.c_char_p, ctypes.c_int, self.KCallBack]
++                self.sdkInterface.sdkLib.kdk_package_install_package_online.restype   = ctypes.c_int
++            else:
++                logging.warning("kdk_package_install_package_online do not find in '%s'", self.SDK_LIBRARY)
++                self.conf2Loaded = False
++                return
++
++            if self.sdkInterface.function_exists("kdk_package_install_package_offline"):
++                self.sdkInterface.sdkLib.kdk_package_install_package_offline.argtypes  = [ctypes.c_char_p, ctypes.c_int, self.KCallBack]
++                self.sdkInterface.sdkLib.kdk_package_install_package_offline.restype   = ctypes.c_int
++            else:
++                logging.warning("kdk_package_install_package_offline do not find in '%s'", self.SDK_LIBRARY)
++                self.conf2Loaded = False
++                return
++
++            if self.sdkInterface.function_exists("kdk_package_remove_package"):
++                self.sdkInterface.sdkLib.kdk_package_remove_package.argtypes  = [ctypes.c_char_p, self.KCallBack]
++                self.sdkInterface.sdkLib.kdk_package_remove_package.restype   = ctypes.c_int
++            else:
++                logging.warning("kdk_package_remove_package do not find in '%s'", self.SDK_LIBRARY)
++                self.conf2Loaded = False
++                return
++
++            # 以下接口不影响sdk安装卸载操作
++            if self.sdkInterface.function_exists("kdk_package_get_name"):
++                self.sdkInterface.sdkLib.kdk_package_get_name.argtypes  = [ctypes.c_char_p]
++                self.sdkInterface.sdkLib.kdk_package_get_name.restype   = ctypes.c_char_p
++            else:
++                logging.warning("kdk_package_get_name do not find in '%s'", self.SDK_LIBRARY)
++
++            if self.sdkInterface.function_exists("kdk_package_is_installed"):
++                self.sdkInterface.sdkLib.kdk_package_is_installed.argtypes  = [ctypes.c_char_p, ctypes.c_char_p]
++                self.sdkInterface.sdkLib.kdk_package_is_installed.restype   = ctypes.c_int
++            else:
++                logging.warning("kdk_package_is_installed do not find in '%s'", self.SDK_LIBRARY)
++
++            self.installLoaded = True
++        except Exception as e:
++            logging.error("conf2_interface_init error: %s", e)
++
++    def package_interface_install(self, uri):
++        _success = False
++
++        try:
++            if not self.installLoaded:
++                logging.error("kdk_package_install_package load library error")
++                return _success
++
++            logging.info("kdk_package_install_package try to install: %s", uri)
++
++            iRet = self.sdkInterface.sdkLib.kdk_package_install_package (uri.encode('utf-8'),
++                                                        InstallMode.KDK_PACKAGE_AUTO.value,
++                                                        self.install_status_changed)
++
++            logging.info("kdk_package_install_package iRet:%d", iRet)
++
++            if iRet == self.KDK_PACKAGE_INSTALL_ERROR:
++                logging.info("kdk_package_install_package KDK_PACKAGE_INSTALL_ERROR")
++            elif iRet == self.KDK_PACKAGE_INSTALL_SUCCESS:
++                _success = True
++                logging.info("kdk_package_install_package KDK_PACKAGE_INSTALL_SUCCESS")
++
++        except Exception as e:
++            logging.error("package_interface_install error: %s", e)
++        
++        return _success
++
++    def package_interface_batch_install(self, pkgs_list):
++        _success = False
++        iRet     = self.KDK_PACKAGE_INSTALL_ERROR
++
++        try:
++            if not self.installLoaded:
++                logging.error("kdk_package_install_package load library error")
++                return _success
++
++            logging.info("kdk_package_install_package try to install: %s", ",".join(pkgs_list))
++            self.batchInstPkgsNum   = len(pkgs_list)
++
++            for pl in pkgs_list:
++                iRet = self.sdkInterface.sdkLib.kdk_package_install_package (pl.encode('utf-8'),
++                                                            InstallMode.KDK_PACKAGE_AUTO.value,
++                                                            self.batch_install_status_changed)
++                self.batchInstPkgsIndex += 1
++
++                if iRet == self.KDK_PACKAGE_INSTALL_ERROR:
++                    break
++
++            logging.info("kdk_package_install_package iRet:%d", iRet)
++
++            if iRet == self.KDK_PACKAGE_INSTALL_ERROR:
++                logging.info("kdk_package_install_package KDK_PACKAGE_INSTALL_ERROR")
++            elif iRet == self.KDK_PACKAGE_INSTALL_SUCCESS:
++                _success = True
++                logging.info("kdk_package_install_package KDK_PACKAGE_INSTALL_SUCCESS")
++
++            self.package_interface_install_clear()
++        except Exception as e:
++            logging.error("package_interface_install error: %s", e)
++        
++        return _success
++
++    def package_interface_remove(self, uri):
++        _success      = False
++        _package_name = ''
++
++        try:
++            if not self.installLoaded:
++                logging.error("kdk_package_install_package load library error")
++                return _success
++
++            if os.path.exists(uri) and uri.endswith('.desktop'):
++                _package_name = self.package_name_from_desktop (uri)
++            else:
++                _package_name = uri
++
++            logging.info("kdk_package_remove_package try to remove: %s", _package_name)
++            iRet = self.sdkInterface.sdkLib.kdk_package_remove_package (_package_name.encode('utf-8'),
++                                                        self.purge_status_changed)
++
++            logging.info("kdk_package_remove_package iRet:%d", iRet)
++
++            if iRet == self.KDK_PACKAGE_INSTALL_ERROR:
++                logging.info("kdk_package_remove_package KDK_PACKAGE_REMOVE_ERROR")
++            elif iRet == self.KDK_PACKAGE_INSTALL_SUCCESS:
++                _success = True
++                logging.info("kdk_package_remove_package KDK_PACKAGE_REMOVE_SUCCESS")
++
++        except Exception as e:
++            logging.error("package_interface_remove error: %s", e)
++
++        return _success
++
++    def package_name_from_desktop(self, desktop_path):
++        _package_name = ''
++
++        try:
++            if self.sdkInterface.sdkLib.kdk_package_get_name:
++                logging.info("package_name_from_desktop try to get _package_name: %s", desktop_path)
++                _package_name = self.sdkInterface.sdkLib.kdk_package_get_name (desktop_path.encode('utf-8')).decode('utf-8').strip()
++            else:
++                logging.error("kdk_package_get_name load library error")
++
++            logging.info("package_name_from_desktop _package_name: %s", _package_name)
++
++        except Exception as e:
++            logging.error("package_name_from_desktop error: %s", e)
++
++        return _package_name
++
++    def package_interface_check_status(self, _name, _version):
++        install_status = -100
++
++        try:
++            if self.sdkInterface.sdkLib.kdk_package_is_installed:
++                if _name:
++                    _name = _name.encode('utf-8')
++                if _version:
++                    _version = _version.encode('utf-8')
++                logging.info("package_interface_check_status try to check _name: %s, _version:%s""", _name, _version)
++                install_status = self.sdkInterface.sdkLib.kdk_package_is_installed (_name, _version)
++            else:
++                logging.error("kdk_package_is_installed load library error")
++
++            logging.info("package_interface_check_status _name: %s, _version:%s, install_status:%s", 
++                         _name, _version, install_status)
++
++        except Exception as e:
++            logging.error("package_interface_check_status error: %s", e)
++
++        return install_status
++
++    def package_interface_install_clear(self):
++        try:
++            self.progress_restore   = 0
++            self.batchInstPkgs      = []
++            self.batchInstPkgsNum   = 0
++            self.batchInstPkgsIndex = 0
++
++        except Exception as e:
++            logging.error("package_interface_check_status error: %s", e)
+diff --git a/backend-immutable/SystemUpdater/packageManager/__init__.py b/backend-immutable/SystemUpdater/packageManager/__init__.py
+new file mode 100644
+index 0000000..e69de29
+diff --git a/backend-immutable/SystemUpdater/packageManager/pmEnums.py b/backend-immutable/SystemUpdater/packageManager/pmEnums.py
+new file mode 100644
+index 0000000..7b375e6
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/packageManager/pmEnums.py
+@@ -0,0 +1,370 @@
++#!/usr/bin/env python
++# -*- coding: utf-8 -*-
++"""enums - Enumerates for apt daemon dbus messages"""
++
++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,
++                            ERROR_NO_PACKAGE,
++                            ERROR_NO_CACHE,
++                            EXIT_CANCELLED,
++                            ERROR_PACKAGE_MANAGER_FAILED,
++                            ERROR_PACKAGE_DOWNLOAD_FAILED,
++                            ERROR_DAEMON_DIED,
++                            ERROR_CACHE_BROKEN,
++                            ERROR_NO_LOCK
++                            )
++
++from aptdaemon.enums import get_error_description_from_enum as get_other_error_description_from_enum
++from aptdaemon.enums import get_error_string_from_enum as get_other_error_string_from_enum
++
++SHOW_DETAILES_CHECK_FLAG = "check-show-details-log"
++
++# 静态变量
++RUNTIME_INSTALL_TYPE = "runtime"
++POWEROFF_INSTALL_TYPE = "pre-poweroff"
++DEFAULT_INSTALL_TYPE = "default"
++DEFAULT_EMPTY_CHATACTER = ''
++INSTALL_DEFAULT_FLAG = 'none'
++INSTALL_FAILED_FALG = 'failed'
++INSTALL_SUCCESS_FLAG = 'success'
++
++CUSTOMIZED_SOURCES = "customized-sources"
++STANDARD_SOURCES = "standard-sources"
++
++CUSTOMIZED_SYSTEM = "customized-system"
++INTERMEDIATE_SYSTEM = "intermediate-system"
++
++STANDARD_SYSTEM = "standard-system"
++
++APT_PRIVATE_PATH = "/etc/kylin-system-updater/apt_private.conf"
++APT_STANDARD_PATH = "/etc/kylin-system-updater/apt_standard.conf"
++
++#系统更新的所有枚举
++PRIORITY_UPGRADE_SUCCCESSED = "priority-upgrade-successed"
++
++#apt update阶段出现的错误解析
++ERROR_PROGRAM_EXCEPTION = "error-program-exception"
++ERROR_UPDATE_DEFAULT_FAILED = "error-update-default-failed"
++ERROR_NOT_SOURCES_PATH = ERROR_NO_LOCK
++
++ERROR_UPDATE_SOURCE_FAILED = "error-update-source-failed"
++ERROR_UPDATE_SOURCE_TIMEOUT = "error-update-source-timeout"
++ERROR_SOURCE_WRITE_DENIED = "error-source-write-denied"
++ERROR_NETWORK_FAILED = "error-network-failed"
++ERROR_NOT_GROUPS_CONFIG = "error-not-groups-config"
++ERROR_NOT_CONFIGPKG_DEPENDENCIES = "error-not-configpkg-dependencies"
++ERROR_NOT_SELFPKG_DEPENDENCIES = "error-not-selfpkg-dependencies"
++ERROR_NOT_FIX_SYSTEM = "error-not-fix-system"
++ERROR_LOAD_CONFIG_FAILED = "error-load-config-failed"
++ERROR_CONFIG_PATH_MISSING = "error-config-path-missing"
++ERROR_SYSTEM_SANITY_FAILED = "error-system-snaity-failed"
++ERROR_SYSTEM_SANITY_WARNING = "error-system-snaity-warning"
++ERROR_NOT_NECESSARY_LIB = "error-not-necessary-lib"
++ERROR_DOWNGRADE_PKGS_LIMIT="error-downgrade-pkgs-limit"
++ERROR_INCOMP_THIRDS_PKGS="error-incomp-thirds-pkgs"
++ERROR_CHECK_UPDATE_TIMEOUT="error-check-update-timeout"
++
++#安装错误
++ERROR_SOFTWARE_INDEX_RROKEN = "error-software-index-broken"
++ERROR_NOT_INIT_PACKAGESINFIO = "error-not-init-packagesinfo"
++ERROR_READ_IMPORTANTLIST_FAILED = "error-read-importantlist-failed"
++ERROR_RESOLVER_FAILED = "error-resolver-failed"
++ERROR_NOT_UPGRADE_PACKAGES = "error-not-upgrade-packages"
++ERROR_REMOVE_ESSENTIAL_PACKAGES = "error-remove-essential-packages"
++ERROR_RUN_SCRIPTS_FAILED = "error-run-scripts-failed"
++ERROR_NOT_DISK_SPACE = "error-not-disk-space"
++ERROR_DEVICE_LOW_BATTERY = "error-device-low-battery"
++ERROR_READ_LOCAL_DEB = "error-read-local-deb"
++ERROR_LOCAL_DEB_FORMAT = "error-local-deb-format"
++ERROR_INSTALL_DEB_BASE = "error-install-deb-base"
++ERROR_INSTALL_DEB_VERIFY = "error-install-deb-verify"
++ERROR_INSTALL_DEB_SECURITY = "error-install-deb-security"
++ERROR_INSTALL_DEB_DPKG = "error-install-deb-dpkg"
++ERROR_INSTALL_DEB_DEPEND = "error-install-deb-depend"
++SUCCESS_INSTALL_DEB = "success-install-deb"
++ERROR_INSTALL_DEB_OTHER = "error-install-deb-other"
++SUCCESS_PURGE_PKG = "success-purge-pkg"
++ERROR_PURGE_PKG_DPKG = "error-purge-pkg-dpkg"
++ERROR_PURGE_PKG_VERIFY = "error-purge-pkg-verify"
++ERROR_PURGE_PKG_TOREMOVE = "error-purge-pkg-toremove"
++ERROR_INSTALL_POWER_OUTAGE = "error-install-power-outage"
++ERROR_INSTALL_TIMEOUT_FAILED = "error-install-timeout-failed"
++
++ERROR_NO_PACKAGE_CACHE = "error-no-package-cache"
++ERROR_NO_OFFLINE_SOURCE = "error-no-offline-source"
++
++_STRINGS_ERROR = {
++    DEFAULT_EMPTY_CHATACTER: '',
++    PRIORITY_UPGRADE_SUCCCESSED: _("Update Manager upgrade is complete, please restart the setting panel before performing the system update."),
++    ERROR_DAEMON_DIED: _("Update Manager exception, please restart the setting panel before performing the system update."),
++
++    #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_READ_IMPORTANTLIST_FAILED: _("Check for update exceptions!"),
++    ERROR_SOFTWARE_INDEX_RROKEN: _("Check for update exceptions!"),
++    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_CONFIG_PATH_MISSING: _("Check for update exceptions!"),
++    ERROR_NOT_SOURCES_PATH: _("Check for update exceptions!"),
++    ERROR_DOWNGRADE_PKGS_LIMIT: _("Check for update exceptions!"),
++    ERROR_SYSTEM_SANITY_FAILED: _("Update conditions not met: Patches do not match"),
++    ERROR_SYSTEM_SANITY_WARNING: _("Update conditions not met: Patches do not match"),
++    ERROR_NOT_NECESSARY_LIB: _("Check for update exceptions!"),
++    ERROR_INCOMP_THIRDS_PKGS: _("Check for update exceptions!"),
++    ERROR_CHECK_UPDATE_TIMEOUT: _("Check for update exceptions!"),
++    ERROR_SOURCE_WRITE_DENIED: _("Check for update exceptions!"),
++
++    #优先升级
++    ERROR_NOT_GROUPS_CONFIG: _("Upgrade configuration acquisition exception."),
++    ERROR_NOT_CONFIGPKG_DEPENDENCIES: _("Upgrade configuration acquisition exception."),
++    ERROR_NOT_SELFPKG_DEPENDENCIES: _("Priority upgrade status exception."),
++    
++    #install
++    EXIT_CANCELLED: _("Failed to fetch"),
++    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_DEVICE_LOW_BATTERY: _("If the battery of the device is insufficient, please plug in the power supply before updating the system."),
++    ERROR_INSTALL_TIMEOUT_FAILED: _(" "),
++    ERROR_READ_LOCAL_DEB:_(" "),
++    ERROR_INSTALL_POWER_OUTAGE:_(" "),
++    ERROR_LOCAL_DEB_FORMAT:_(" "),
++    ERROR_INSTALL_DEB_BASE:_(" "),
++    ERROR_INSTALL_DEB_VERIFY:_(" "),
++    ERROR_INSTALL_DEB_SECURITY:_(" "),
++    ERROR_INSTALL_DEB_DPKG:_(" "),
++    ERROR_INSTALL_DEB_DEPEND:_(" "),
++    ERROR_CACHE_BROKEN:_(" "),
++    SUCCESS_INSTALL_DEB:_(" "),
++    ERROR_INSTALL_DEB_OTHER:_(" "),
++    SUCCESS_PURGE_PKG:_(" "),
++    ERROR_PURGE_PKG_DPKG:_(" "),
++    ERROR_PURGE_PKG_VERIFY:_(" "),
++    ERROR_PURGE_PKG_TOREMOVE:_(" "),
++
++    ERROR_NO_OFFLINE_SOURCE:_(" "),
++    ERROR_NO_PACKAGE_CACHE: _(" ")
++    }
++
++_DESCS_ERROR = {
++    PRIORITY_UPGRADE_SUCCCESSED: '',
++    
++    DEFAULT_EMPTY_CHATACTER: '',
++    ERROR_PROGRAM_EXCEPTION: _("Program exception, please contact the administrator to solve."),
++    #update 
++    ERROR_NOT_SOURCES_PATH: _(" "),
++    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_NOT_GROUPS_CONFIG: _("Unable to get group configuration package, Please check if the configuration package exists in the software source repository."),
++    ERROR_NOT_INIT_PACKAGESINFIO: _("An unresolvable problem occurred while initializing the package."),
++    ERROR_SOFTWARE_INDEX_RROKEN: _("Software index is broken") + _("It is impossible to install or remove any software. "
++                    "Please use the package manager \"Synaptic\" or run "
++                    "\"sudo apt-get install -f\" in a terminal to fix "
++                    "this issue at first."),
++    ERROR_READ_IMPORTANTLIST_FAILED: _("read important list failed"),
++    ERROR_CONFIG_PATH_MISSING: _("Patch configuration file directory does not exitst."),
++    ERROR_NOT_CONFIGPKG_DEPENDENCIES: _("Unable to install group configuration package, Please check the configuration package related dependencies."),
++    ERROR_NOT_SELFPKG_DEPENDENCIES: _("Unable to perform priority upgrade, please check the dependency related to the priority upgrade package."),
++
++    ERROR_DOWNGRADE_PKGS_LIMIT: _("Update patchs do not match and too many downgraded packages."),
++    ERROR_LOAD_CONFIG_FAILED: _("The system update configuration file is read abnormally, please check if the system update configuration file format is correct."),
++    ERROR_NOT_FIX_SYSTEM: _("The system APT environment is abnormal, please check the system APT environment."),
++    ERROR_SYSTEM_SANITY_FAILED: _("The version does not match the patch check."),
++    ERROR_SYSTEM_SANITY_WARNING: _(" "),
++    ERROR_NOT_NECESSARY_LIB: _("The system necessary library matching failed."),
++    ERROR_INCOMP_THIRDS_PKGS: _("Third-party application is not compatible with the patch."),
++    ERROR_CHECK_UPDATE_TIMEOUT: _("Check the update timeout, please try again later."),
++    ERROR_SOURCE_WRITE_DENIED: _("Write Source file was denied, please repair the file permission."),
++
++    #install
++    EXIT_CANCELLED: _("_Cancel Upgrade"),
++    ERROR_RESOLVER_FAILED: _("  "),
++    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_CACHE_BROKEN:_("The package system is broken, please contact the administrator to solve."),
++    ERROR_NOT_DISK_SPACE: _(" "),
++    ERROR_DEVICE_LOW_BATTERY: _(" "),
++    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."),
++    ERROR_INSTALL_POWER_OUTAGE: _("The installation process is abnormally shut down or down."),
++    ERROR_INSTALL_DEB_VERIFY:_(" "),
++    ERROR_INSTALL_DEB_SECURITY:_(" "),
++    ERROR_INSTALL_DEB_DPKG:_(" "),
++    ERROR_INSTALL_DEB_DEPEND:_(" "),
++    SUCCESS_INSTALL_DEB:_(" "),
++    ERROR_INSTALL_DEB_OTHER:_(" "),
++    SUCCESS_PURGE_PKG:_(" "),
++    ERROR_PURGE_PKG_DPKG:_(" "),
++    ERROR_PURGE_PKG_VERIFY:_(" "),
++    ERROR_PURGE_PKG_TOREMOVE:_(" "),
++    ERROR_NO_OFFLINE_SOURCE:_("If the offline source is not detected, please remount it and update it."),
++
++    ERROR_NO_PACKAGE_CACHE: _("Package is not in cache"),
++    ERROR_INSTALL_TIMEOUT_FAILED: _("Installation timeout and the installation is exited.")
++    }
++
++_CODE_ERROR = {
++    DEFAULT_EMPTY_CHATACTER: '',
++    # other 仅测试使用
++    ERROR_PROGRAM_EXCEPTION: "#0000",
++    ERROR_RESOLVER_FAILED:"#0001",
++
++    #update 
++    ERROR_UPDATE_SOURCE_FAILED: "#0100",
++    ERROR_UPDATE_SOURCE_TIMEOUT: "#0101",
++    ERROR_NETWORK_FAILED: "#0102",
++    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",
++    ERROR_NO_CACHE: "#0116",
++    ERROR_SYSTEM_SANITY_FAILED: "#0117",
++    ERROR_SYSTEM_SANITY_WARNING: "#0118",
++    ERROR_NOT_NECESSARY_LIB:"#0119",
++    ERROR_INCOMP_THIRDS_PKGS:"#0120",
++    ERROR_CHECK_UPDATE_TIMEOUT:"#0121",
++    ERROR_SOURCE_WRITE_DENIED:"#0122",
++    ERROR_CONFIG_PATH_MISSING:"#0123",
++
++    #install
++    ERROR_PACKAGE_MANAGER_FAILED: "#0200",
++    ERROR_NOT_UPGRADE_PACKAGES: "#0201",
++    ERROR_REMOVE_ESSENTIAL_PACKAGES: "#0202",
++    ERROR_PACKAGE_DOWNLOAD_FAILED: "#0203",
++    ERROR_NOT_DISK_SPACE: "#0204",
++    ERROR_READ_LOCAL_DEB: "#0205",
++    ERROR_LOCAL_DEB_FORMAT: "#0206",
++    ERROR_INSTALL_DEB_BASE: "#0207",
++    ERROR_DEVICE_LOW_BATTERY: "#0208",
++    ERROR_NO_PACKAGE: "#0209",
++    ERROR_NO_PACKAGE_CACHE: "#0210",
++    ERROR_INSTALL_DEB_VERIFY:"#0211",
++    ERROR_INSTALL_DEB_SECURITY:"#0212",
++    ERROR_INSTALL_DEB_DPKG:"#0213",
++    ERROR_INSTALL_DEB_DEPEND:"#0214",
++    ERROR_CACHE_BROKEN:"#0215",
++    ERROR_NO_OFFLINE_SOURCE:"#0216",
++    ERROR_INSTALL_POWER_OUTAGE:"#0217",
++    ERROR_INSTALL_TIMEOUT_FAILED: "#0218",
++
++    SUCCESS_INSTALL_DEB:"#0219",
++    ERROR_INSTALL_DEB_OTHER:"#0220",
++    ERROR_PURGE_PKG_DPKG:"#0221",
++    ERROR_PURGE_PKG_VERIFY:"#0222",
++    ERROR_PURGE_PKG_TOREMOVE:"#0223",
++    SUCCESS_PURGE_PKG:"#0230",
++
++    # other 
++    EXIT_CANCELLED: "#0300"
++    }
++
++
++#UPGRADE MONITOR STATUS
++MONIT_DETECT = "step-updatedetect"
++MONIT_DEPRESOLUT = "step-depresolution"
++MONIT_DOWNLOAD = "step-downfinish"
++MONIT_INSTALL = "step-installing"
++MONIT_FINISH = "step-finish"
++MONIT_INSTALLDEB = "step-installdeb"
++
++SOURCE_NAME = {
++    'kylin-installer':_("Kylin Installer"),
++    'kylin-uninstaller':_("Kylin Uninstaller"),
++    'kylin-background-upgrade':_("Kylin Background Upgrade"),
++    'kylin-software-center':_("Kylin Software Center"),
++}
++
++CALLER = {
++    'kylin-installer':"Kylin Installer",
++    'kylin-uninstaller':"Kylin Uninstaller",
++    'kylin-background-upgrade':"Kylin Background Upgrade",
++    '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",
++    'kylin-installer-self':"cn.kylin.installer.self.action",
++    'kylin-uninstaller-self':"cn.kylin.uninstaller.self.action",
++    'kylin-software-center-self':"cn.kylin.software.center.self.action",
++    'kylin-system-updater-self':"cn.kylinos.KylinSystemUpdater.self.action",
++}
++
++def get_error_description_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 _DESCS_ERROR[enum]
++    except KeyError:
++        return get_other_error_description_from_enum(enum)
++
++def get_error_num_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.
++
++    :param enum: The transaction error enum, e.g. :data:`ERROR_NO_LOCK`.
++    :returns: The description string.
++    """
++    try:
++        return _STRINGS_ERROR[enum]
++    except KeyError:
++        return get_other_error_string_from_enum(enum)
++
++
++def get_source_name_from_enum(enum):
++    try:
++        return _(SOURCE_NAME[enum])
++    except KeyError:
++        return _("Kylin System Updater")
++
++def get_caller_from_enum(enum):
++    try:
++        return CALLER[enum]
++    except KeyError:
++        return _("Kylin System Updater")
++
++def get_policykit_authority_action_enum(enum):
++    try:
++        return PolicyKit_Authority_Action[enum]
++    except KeyError:
++        if enum.endswith("-self"):
++            return "cn.kylinos.KylinSystemUpdater.self.action" #默认配置
++        else:
++            return "cn.kylinos.KylinSystemUpdater.action" #默认配置
++
++# vim:ts=4:sw=4:et
+diff --git a/backend-immutable/SystemUpdater/packageManager/pmUtils.py b/backend-immutable/SystemUpdater/packageManager/pmUtils.py
+new file mode 100644
+index 0000000..872988f
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/packageManager/pmUtils.py
+@@ -0,0 +1,932 @@
++# utils.py
++# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
++#
++#  Copyright (c) 2004-2013 Canonical
++#
++#  Authors: Michael Vogt <mvo@debian.org>
++#           Michael Terry <michael.terry@canonical.com>
++#
++#  This program is free software; you can redistribute it and/or
++#  modify it under the terms of the GNU General Public License as
++#  published by the Free Software Foundation; either version 2 of the
++#  License, or (at your option) any later version.
++#
++#  This program is distributed in the hope that it will be useful,
++#  but WITHOUT ANY WARRANTY; without even the implied warranty of
++#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++#  GNU General Public License for more details.
++#
++#  You should have received a copy of the GNU General Public License
++#  along with this program; if not, write to the Free Software
++#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++#  USA
++import re
++import os
++import sys
++import apt
++import dbus
++import time
++import shutil
++import locale
++import psutil
++import logging
++import subprocess
++from ctypes import *
++from copy import copy
++from math import ceil
++from defer import Deferred
++from gettext import gettext as _
++from gettext import ngettext
++from urllib.parse import urlsplit
++from apt.debfile import DebPackage
++from SystemUpdater.Core.errors import *
++from stat import (S_IMODE, ST_MODE, S_IXUSR)
++from SystemUpdater.packageManager.pmEnums import *
++
++import apt_pkg
++apt_pkg.init_config()
++
++from urllib.request import (
++                        ProxyHandler,
++                        Request,
++                        build_opener,
++                        install_opener,
++                        urlopen,
++                    )
++
++# 禁止关机锁文件路径
++VERIFY_SO = "libkylin_signtool.so"
++
++class ExecutionTime(object):
++    """
++    Helper that can be used in with statements to have a simple
++    measure of the timing of a particular block of code, e.g.
++    with ExecutionTime("db flush"):
++        db.flush()
++    """
++    def __init__(self, info=""):
++        self.info = info
++
++    def __enter__(self):
++        self.now = time.time()
++
++    def __exit__(self, type, value, stack):
++        print("%s: %s" % (self.info, time.time() - self.now))
++
++
++def get_string_with_no_auth_from_source_entry(entry):
++    tmp = copy(entry)
++    url_parts = urlsplit(tmp.uri)
++    if url_parts.username:
++        tmp.uri = tmp.uri.replace(url_parts.username, "hidden-u")
++    if url_parts.password:
++        tmp.uri = tmp.uri.replace(url_parts.password, "hidden-p")
++    return str(tmp)
++
++
++def is_unity_running():
++    """ return True if Unity is currently running """
++    unity_running = False
++    try:
++        import dbus
++        bus = dbus.SessionBus()
++        unity_running = bus.name_has_owner("com.canonical.Unity")
++    except Exception:
++        logging.exception("could not check for Unity dbus service")
++    return unity_running
++
++#清空上次输出的分组JSON文件
++def make_empty_dir(path):
++    #清空 升级列表
++    if not os.path.exists(path):
++        os.makedirs(path)
++        logging.info('making the ConfigPath(%s) is complete...',path)
++    else:
++        shutil.rmtree(path)
++        os.makedirs(path)
++        logging.info('Emptying the ConfigPath(%s) is complete...',path)
++
++def is_child_of_process_name(processname, pid=None):
++    if not pid:
++        pid = os.getpid()
++    while pid > 0:
++        stat_file = "/proc/%s/stat" % pid
++        with open(stat_file) as stat_f:
++            stat = stat_f.read()
++        # extract command (inside ())
++        command = stat.partition("(")[2].rpartition(")")[0]
++        if command == processname:
++            return True
++        # get parent (second to the right of command) and check that next
++        pid = int(stat.rpartition(")")[2].split()[1])
++    return False
++
++
++def inside_chroot():
++    """ returns True if we are inside a chroot
++    """
++    # if there is no proc or no pid 1 we are very likely inside a chroot
++    if not os.path.exists("/proc") or not os.path.exists("/proc/1"):
++        return True
++    # if the inode is differnt for pid 1 "/" and our "/"
++    return os.stat("/") != os.stat("/proc/1/root")
++
++
++def wrap(t, width=70, subsequent_indent=""):
++    """ helpers inspired after textwrap - unfortunately
++        we can not use textwrap directly because it break
++        packagenames with "-" in them into new lines
++    """
++    out = ""
++    for s in t.split():
++        if (len(out) - out.rfind("\n")) + len(s) > width:
++            out += "\n" + subsequent_indent
++        out += s + " "
++    return out
++
++
++def twrap(s, **kwargs):
++    msg = ""
++    paras = s.split("\n")
++    for par in paras:
++        s = wrap(par, **kwargs)
++        msg += s + "\n"
++    return msg
++
++
++def lsmod():
++    " return list of loaded modules (or [] if lsmod is not found) "
++    modules = []
++    if not os.path.exists("/sbin/lsmod"):
++        return []
++    p = subprocess.Popen(["/sbin/lsmod"], stdout=subprocess.PIPE,
++                         universal_newlines=True)
++    lines = p.communicate()[0].split("\n")
++    # remove heading line: "Modules Size Used by"
++    del lines[0]
++    # add lines to list, skip empty lines
++    for line in lines:
++        if line:
++            modules.append(line.split()[0])
++    return modules
++
++
++def check_and_fix_xbit(path):
++    " check if a given binary has the executable bit and if not, add it"
++    if not os.path.exists(path):
++        return
++    mode = S_IMODE(os.stat(path)[ST_MODE])
++    if not ((mode & S_IXUSR) == S_IXUSR):
++        os.chmod(path, mode | S_IXUSR)
++
++
++def country_mirror():
++    " helper to get the country mirror from the current locale "
++    # special cases go here
++    lang_mirror = {'c': ''}
++    # no lang, no mirror
++    if 'LANG' not in os.environ:
++        return ''
++    lang = os.environ['LANG'].lower()
++    # check if it is a special case
++    if lang[:5] in lang_mirror:
++        return lang_mirror[lang[:5]]
++    # now check for the most comon form (en_US.UTF-8)
++    if "_" in lang:
++        country = lang.split(".")[0].split("_")[1]
++        if "@" in country:
++            country = country.split("@")[0]
++        return country + "."
++    else:
++        return lang[:2] + "."
++    return ''
++
++def get_dist_version():
++    " return the version of the current running distro "
++    # then check the real one
++    from subprocess import Popen, PIPE
++    p = Popen(["lsb_release", "-r", "-s"], stdout=PIPE,
++            universal_newlines=True)
++    res = p.wait()
++    if res != 0:
++        sys.stderr.write("lsb_release returned exitcode: %i\n" % res)
++        return "unknown distribution"
++    desc = p.stdout.readline().strip()
++    p.stdout.close()
++    return desc
++
++
++class HeadRequest(Request):
++    def get_method(self):
++        return "HEAD"
++
++
++def url_downloadable(uri, debug_func=None):
++    """
++    helper that checks if the given uri exists and is downloadable
++    (supports optional debug_func function handler to support
++     e.g. logging)
++
++    Supports http (via HEAD) and ftp (via size request)
++    """
++    if not debug_func:
++        lambda x: True
++    debug_func("url_downloadable: %s" % uri)
++    (scheme, netloc, path, querry, fragment) = urlsplit(uri)
++    debug_func("s='%s' n='%s' p='%s' q='%s' f='%s'" % (scheme, netloc, path,
++                                                       querry, fragment))
++    if scheme in ("http", "https"):
++        try:
++            http_file = urlopen(HeadRequest(uri))
++            http_file.close()
++            if http_file.code == 200:
++                return True
++            return False
++        except Exception as e:
++            debug_func("error from httplib: '%s'" % e)
++            return False
++    elif scheme == "ftp":
++        import ftplib
++        try:
++            f = ftplib.FTP(netloc)
++            f.login()
++            f.cwd(os.path.dirname(path))
++            size = f.size(os.path.basename(path))
++            f.quit()
++            if debug_func:
++                debug_func("ftplib.size() returned: %s" % size)
++            if size != 0:
++                return True
++        except Exception as e:
++            if debug_func:
++                debug_func("error from ftplib: '%s'" % e)
++            return False
++    return False
++
++def is_chinese(string):
++    """
++    检查整个字符串是否包含中文
++    :param string: 需要检查的字符串
++    :return: bool
++    """
++    for ch in string:
++        if u'\u4e00' <= ch <= u'\u9fff':
++            return True
++
++    return False
++
++def init_proxy(gsettings=None):
++    """ init proxy settings
++
++    * use apt.conf http proxy if present,
++    * otherwise look into synaptics config file,
++    * otherwise the default behavior will use http_proxy environment
++      if present
++    """
++    SYNAPTIC_CONF_FILE = "/root/.synaptic/synaptic.conf"
++    proxies = {}
++    # generic apt config wins
++    if apt_pkg.config.find("Acquire::http::Proxy") != '':
++        proxies["http"] = apt_pkg.config.find("Acquire::http::Proxy")
++    # then synaptic
++    elif os.path.exists(SYNAPTIC_CONF_FILE):
++        cnf = apt_pkg.Configuration()
++        apt_pkg.read_config_file(cnf, SYNAPTIC_CONF_FILE)
++        use_proxy = cnf.find_b("Synaptic::useProxy", False)
++        if use_proxy:
++            proxy_host = cnf.find("Synaptic::httpProxy")
++            proxy_port = str(cnf.find_i("Synaptic::httpProxyPort"))
++            if proxy_host and proxy_port:
++                proxies["http"] = "http://%s:%s/" % (proxy_host, proxy_port)
++    if apt_pkg.config.find("Acquire::https::Proxy") != '':
++        proxies["https"] = apt_pkg.config.find("Acquire::https::Proxy")
++    elif "http" in proxies:
++        proxies["https"] = proxies["http"]
++    # if we have a proxy, set it
++    if proxies:
++        # basic verification
++        for proxy in proxies.values():
++            if not re.match("https?://\\w+", proxy):
++                print("proxy '%s' looks invalid" % proxy, file=sys.stderr)
++                return
++        proxy_support = ProxyHandler(proxies)
++        opener = build_opener(proxy_support)
++        install_opener(opener)
++        if "http" in proxies:
++            os.putenv("http_proxy", proxies["http"])
++        if "https" in proxies:
++            os.putenv("https_proxy", proxies["https"])
++    return proxies
++
++
++def on_battery():
++    """
++    Check via dbus if the system is running on battery.
++    This function is using UPower per default, if UPower is not
++    available it falls-back to DeviceKit.Power.
++    """
++    try:
++        import dbus
++        bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
++        try:
++            devobj = bus.get_object('org.freedesktop.UPower',
++                                    '/org/freedesktop/UPower')
++            dev = dbus.Interface(devobj, 'org.freedesktop.DBus.Properties')
++            return dev.Get('org.freedesktop.UPower', 'OnBattery')
++        except dbus.exceptions.DBusException as e:
++            error_unknown = 'org.freedesktop.DBus.Error.ServiceUnknown'
++            if e._dbus_error_name != error_unknown:
++                raise
++            devobj = bus.get_object('org.freedesktop.DeviceKit.Power',
++                                    '/org/freedesktop/DeviceKit/Power')
++            dev = dbus.Interface(devobj, "org.freedesktop.DBus.Properties")
++            return dev.Get("org.freedesktop.DeviceKit.Power", "on_battery")
++    except Exception:
++        #import sys
++        #print("on_battery returned error: ", e, file=sys.stderr)
++        return False
++
++
++def str_to_bool(str):
++    if str == "0" or str.upper() == "FALSE":
++        return False
++    return True
++
++
++def get_lang():
++    import logging
++    try:
++        (locale_s, encoding) = locale.getdefaultlocale()
++        return locale_s
++    except Exception:
++        logging.exception("gedefaultlocale() failed")
++        return None
++
++
++def get_ubuntu_flavor(cache=None):
++    """ try to guess the flavor based on the running desktop """
++    # this will (of course) not work in a server environment,
++    # but the main use case for this is to show the right
++    # release notes.
++    pkg = get_ubuntu_flavor_package(cache=cache)
++    return pkg.split('-', 1)[0]
++
++
++# def _load_meta_pkg_list():
++#     # This could potentially introduce a circular dependency, but the config
++#     # parser logic is simple, and doesn't rely on any UpdateManager code.
++#     from DistUpgrade.DistUpgradeConfigParser import DistUpgradeConfig
++#     parser = DistUpgradeConfig('/usr/share/ubuntu-release-upgrader')
++#     return parser.getlist('Distro', 'MetaPkgs')
++
++
++def get_ubuntu_flavor_package(cache=None):
++    """ try to guess the flavor metapackage based on the running desktop """
++    # From spec, first if ubuntu-desktop is installed, use that.
++    # Second, grab first installed one from DistUpgrade.cfg.
++    # Lastly, fallback to ubuntu-desktop again.
++    meta_pkgs = ['ubuntu-desktop']
++
++    # try:
++    #     meta_pkgs.extend(sorted(_load_meta_pkg_list()))
++    # except Exception as e:
++    #     print('Could not load list of meta packages:', e)
++
++    if cache is None:
++        cache = apt.Cache()
++    for meta_pkg in meta_pkgs:
++        cache_pkg = cache[meta_pkg] if meta_pkg in cache else None
++        if cache_pkg and cache_pkg.is_installed:
++            return meta_pkg
++    return 'ubuntu-desktop'
++
++
++def get_ubuntu_flavor_name(cache=None):
++    """ try to guess the flavor name based on the running desktop """
++    pkg = get_ubuntu_flavor_package(cache=cache)
++    lookup = {'ubuntustudio-desktop': 'Ubuntu Studio'}
++    if pkg in lookup:
++        return lookup[pkg]
++    elif pkg.endswith('-desktop'):
++        return capitalize_first_word(pkg.rsplit('-desktop', 1)[0])
++    elif pkg.endswith('-netbook'):
++        return capitalize_first_word(pkg.rsplit('-netbook', 1)[0])
++    else:
++        return 'Ubuntu'
++
++
++# Unused by update-manager, but still used by ubuntu-release-upgrader
++def error(parent, summary, message):
++    import gi
++    gi.require_version("Gtk", "3.0")
++    from gi.repository import Gtk, Gdk
++    d = Gtk.MessageDialog(parent=parent,
++                          flags=Gtk.DialogFlags.MODAL,
++                          type=Gtk.MessageType.ERROR,
++                          buttons=Gtk.ButtonsType.CLOSE)
++    d.set_markup("<big><b>%s</b></big>\n\n%s" % (summary, message))
++    d.realize()
++    d.get_window().set_functions(Gdk.WMFunction.MOVE)
++    d.set_title("")
++    d.run()
++    d.destroy()
++    return False
++
++def _split_package_id(package):
++    """Return the name, the version number and the release of the
++    specified package."""
++    if ":" in package:
++        name, arch = package.split(":", 1)
++        # release = None
++    # elif "/" in package:
++    #     name, release = package.split("/", 1)
++    #     version = None
++    else:
++        name = package
++        arch = None
++    return name, arch
++
++
++def get_config_patch():
++    #检查组配置文件当前的目录
++    NOW_UPDATE_CONFIG = '/usr/share/kylin-update-desktop-config/config/'
++    OLD_UPDATE_CONFIG = '/usr/share/kylin-update-desktop-config/data/'
++    if os.path.exists(NOW_UPDATE_CONFIG):
++        return NOW_UPDATE_CONFIG
++    elif os.path.exists(OLD_UPDATE_CONFIG):
++        return NOW_UPDATE_CONFIG
++    else:
++        return NOW_UPDATE_CONFIG
++
++def get_broken_details(cache,now=True):
++    """Return a message which provides debugging information about
++    broken packages.
++
++    This method is basically a Python implementation of apt-get.cc's
++    ShowBroken.
++
++    Keyword arguments:
++    trans -- the corresponding transaction
++    #表示当前系统apt已经破损的话是True 如果是安装软件包讲导致破损的话是False
++    now -- if we check currently broken dependecies or the installation
++            candidate
++    """
++    msg = _("The following packages have unmet dependencies:")
++    msg += "\n\n"
++    for pkg in cache:
++        if not ((now and pkg.is_now_broken) or
++                (not now and pkg.is_inst_broken)):
++            continue
++        msg += "%s: " % pkg.name
++        #获取出现问题的包的版本
++        if now:
++            version = pkg.installed
++        else:
++            version = pkg.candidate
++        indent = " " * (len(pkg.name) + 2)
++        dep_msg = ""
++        #拿取依赖关系
++        for dep in version.dependencies:
++            or_msg = ""
++            for base_dep in dep.or_dependencies:
++                if or_msg:
++                    or_msg += "or\n"
++                    or_msg += indent
++                # Check if it's an important dependency
++                # See apt-pkg/depcache.cc IsImportantDep
++                # See apt-pkg/pkgcache.cc IsCritical()
++                if not (base_dep.rawtype in ["Depends","PreDepends",
++                                                "Obsoletes", "DpkgBreaks",
++                                                "Conflicts"] or
++                        (apt_pkg.config.find_b("APT::Install-Recommends",
++                                                False) and
++                        base_dep.rawtype == "Recommends") or
++                        (apt_pkg.config.find_b("APT::Install-Suggests",
++                                                False) and
++                            base_dep.rawtype == "Suggests")):
++                    continue
++                # Get the version of the target package
++                try:
++                    pkg_name,pkg_arch = _split_package_id(base_dep.name)
++                    pkg_dep = cache[pkg_name]
++                except KeyError:
++                    dep_version = None
++                else:
++                    if now:
++                        dep_version = pkg_dep.installed
++                    else:
++                        dep_version = pkg_dep.candidate
++                # We only want to display dependencies which cannot
++                # be satisfied
++                if dep_version and not apt_pkg.check_dep(base_dep.version,
++                                                            base_dep.relation,
++                                                            dep_version.version):
++                    break
++                or_msg = "%s: %s " % (base_dep.rawtype, base_dep.name)
++                if base_dep.version:
++                    or_msg += "(%s %s) " % (base_dep.relation,
++                                            base_dep.version)
++                if cache.is_virtual_package(base_dep.name):
++                    or_msg += _("but it is a virtual package")
++                #表示这个依赖包没有安装 源里面没有
++                elif not dep_version:
++                    if now:
++                        or_msg += _("but it is not installed")
++                    else:
++                        #要依赖包 不存在时走此
++                        or_msg += _("but it is not going to "
++                                                "be installed")
++                #表示安装的版本与需要的版本不一致  在这个地方来再进行递归安装判断 具体那些包造成的不能安装
++                elif now:
++                    # TRANSLATORS: %s is a version number
++                    or_msg += (_("but %s is installed") %
++                                dep_version.version)
++                else:
++                    #安装之后出现破损的话走这里
++                    # TRANSLATORS: %s is a version number
++                    or_msg += (_("but %s is to be installed") %
++                                dep_version.version)
++            else:
++                # Only append an or-group if at least one of the
++                # dependencies cannot be satisfied
++                if dep_msg:
++                    dep_msg += indent
++                dep_msg += or_msg
++                dep_msg += "\n"
++        msg += dep_msg
++    return msg
++
++
++def humanize_size(bytes):
++    """
++    Convert a given size in bytes to a nicer better readable unit
++    """
++
++    if bytes < 1000 * 1000:
++        # to have 0 for 0 bytes, 1 for 0-1000 bytes and for 1 and above
++        # round up
++        size_in_kb = int(ceil(bytes / float(1000)))
++        # TRANSLATORS: download size of small updates, e.g. "250 kB"
++        return ngettext("%(size).0f kB", "%(size).0f kB", size_in_kb) % {
++            "size": size_in_kb}
++    else:
++        # TRANSLATORS: download size of updates, e.g. "2.3 MB"
++        return locale.format_string(_("%.1f MB"), bytes / 1000.0 / 1000.0)
++
++
++def get_arch():
++    return apt_pkg.config.find("APT::Architecture")
++
++
++def is_port_already_listening(port):
++    """ check if the current system is listening on the given tcp port """
++    # index in the line
++    INDEX_LOCAL_ADDR = 1
++    #INDEX_REMOTE_ADDR = 2
++    INDEX_STATE = 3
++    # state (st) that we care about
++    STATE_LISTENING = '0A'
++    # read the data
++    with open("/proc/net/tcp") as net_tcp:
++        for line in net_tcp.readlines():
++            line = line.strip()
++            if not line:
++                continue
++            # split, values are:
++            #   sl  local_address rem_address   st tx_queue rx_queue tr
++            #   tm->when retrnsmt   uid  timeout inode
++            values = line.split()
++            state = values[INDEX_STATE]
++            if state != STATE_LISTENING:
++                continue
++            local_port_str = values[INDEX_LOCAL_ADDR].split(":")[1]
++            local_port = int(local_port_str, 16)
++            if local_port == port:
++                return True
++    return False
++
++
++def iptables_active():
++    """ Return True if iptables is active """
++    iptables_empty = """Chain INPUT (policy ACCEPT)
++target     prot opt source               destination
++
++Chain FORWARD (policy ACCEPT)
++target     prot opt source               destination
++
++Chain OUTPUT (policy ACCEPT)
++target     prot opt source               destination
++"""
++    if os.getuid() != 0:
++        raise OSError("Need root to check the iptables state")
++    if not os.path.exists("/sbin/iptables"):
++        return False
++    out = subprocess.Popen(["iptables", "-nL"],
++                           stdout=subprocess.PIPE,
++                           universal_newlines=True).communicate()[0]
++    if out == iptables_empty:
++        return False
++    return True
++
++
++def capitalize_first_word(string):
++    """ this uppercases the first word's first letter
++    """
++    if len(string) > 1 and string[0].isalpha() and not string[0].isupper():
++        return string[0].capitalize() + string[1:]
++    return string
++
++
++def get_package_label(pkg):
++    """ this takes a package synopsis and uppercases the first word's
++        first letter
++    """
++    name = getattr(pkg.candidate, "summary", "")
++    return capitalize_first_word(name)
++
++# 查看uu进程是否需要kill
++def kill_process(path):
++    try:
++        # 判断文件是否存在
++            if (os.path.exists(path)):
++                with open(path, "r") as f:
++                    pid = f.read()
++                if len(pid) == 0:
++                    return False
++                logging.info("Unattended Upgrades run path: %d. ", int(pid))
++                os.kill(int(pid), 9)
++                logging.info('Unattended Upgrades is running, kill pid: %d. ', int(pid))
++            else:
++                logging.warning('%s is not exist.', path)
++    except Exception as e:
++        logging.error(e)
++        return False
++    return True
++
++def whether_to_quit_uu():
++    osreleasedict={}
++    try:
++        with open('/etc/os-release') as f:
++            lines = f.readlines()
++            for line in lines:
++                ls = line.strip().split('=',1)
++                osreleasedict.update({ls[0]:ls[1].strip('"')})
++    except Exception as e:
++        pass
++    if 'SUB_PROJECT_CODENAME' not in osreleasedict.keys():
++        osreleasedict.update({'SUB_PROJECT_CODENAME':''})
++    if 'PROJECT_CODENAME' in osreleasedict:
++        if osreleasedict['PROJECT_CODENAME']=='V10SP1-edu':
++            if 'SUB_PROJECT_CODENAME' in osreleasedict:
++                if osreleasedict['SUB_PROJECT_CODENAME']=='mavis':
++                    return False
++                else:
++                    logging.info("SUB_PROJECT_CODENAME != mavis")
++            else:
++                logging.info("no SUB_PROJECT_CODENAME")
++        else:
++            logging.info("PROJECT_CODENAME != V10SP1-edu")
++    else:
++        logging.info("no PROJECT_CODENAME")
++    
++    return True
++
++def get_proc_from_dbus_name(dbus_name, bus=None):
++    """Return a deferred that gets the id of process owning the given
++    system D-Bus name.
++    """
++
++    if not bus:
++        bus = dbus.SystemBus()
++    bus_obj = bus.get_object("org.freedesktop.DBus",
++                            "/org/freedesktop/DBus/Bus")
++    pid = bus_obj.GetConnectionUnixProcessID(dbus_name,
++                                    dbus_interface="org.freedesktop.DBus")
++    proc = psutil.Process(int(pid))
++
++    # with open("/proc/%s/status" % pid) as process:
++    #     values = [v for v in process.readlines() if v.startswith("Uid:")]
++    # uid = int(values[0].split()[1])
++
++    # #检查是否root用户执行
++    # if uid == 0:
++    #     return "root"
++
++    return proc.name()
++
++#判断是否为光盘源
++#光盘源格式 deb file:///home/someone/packs/
++def is_offline_source():
++    try:
++        DIR_MRDIA = "/media/OfflineSource/"
++        if os.path.exists(DIR_MRDIA):
++            for second_dir in os.listdir(DIR_MRDIA):
++                #到/media/OfflineSource/
++                check_dir_two = DIR_MRDIA + second_dir + "/"
++                
++                if not os.path.isdir(check_dir_two):
++                    continue
++                check_file = check_dir_two + "ss.map"
++
++                if os.path.exists(check_file):
++                    return True
++            #没有返回存在光盘源就说明不存在
++            return False
++        else:
++            return False
++    except Exception as e:
++        logging.warning(str(e))
++        return False
++
++def deb_format_check(deb_uri):
++    format_check = False
++
++    try:
++        if not os.path.isfile(deb_uri):
++            return format_check
++
++        DebPackage(deb_uri)
++        format_check = True
++        logging.info("deb_format_check '%s' legal", deb_uri)
++    except Exception as e:
++        logging.error(e)
++        
++    return format_check
++
++def deb_verify(deb_path):
++    logging.info("Verify pkg:%s.",deb_path)
++    _deb_path = str(deb_path)
++    _verify_status = False
++    try:
++        if not deb_format_check(_deb_path) or not kysec_authority():
++            _verify_status = True
++            return _verify_status
++
++        # # 加载验证签名库 , 验签接口暂时无法调用
++        if not os.path.isfile("/usr/bin/kylinsigntool"):
++            logging.error("SOF_InitializeEx error!")
++            return _verify_status
++        args = ["/usr/bin/kylinsigntool", "-v", _deb_path]
++        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() \
++                or "Deb signature does not exist" in str(ret.stdout).strip() or "签名不存在" in str(ret.stdout).strip() \
++                or "证书验证失败" in str(ret.stdout).strip():
++            logging.info("Signature Verified failed!")
++        elif "Signature Verified Ok" in str(ret.stdout).strip() or "签名验证成功" in str(ret.stdout).strip() \
++                or "Certificate verification is successful" in str(ret.stdout).strip() or "证书验证成功" in str(ret.stdout).strip():
++            logging.info("Signature Verified Ok!")
++            _verify_status = True
++        else:
++            logging.error("Signature Verified failed:%s.",ret)
++    except Exception as e:
++        logging.error(e)
++    return _verify_status
++
++
++def PolicyKit_Authority(details = '', sender = None, authentication = False, source=''):
++    deferred = Deferred()
++    try:        
++        #用户鉴权
++        logging.info("Authentication via PolicyKit .")
++        details = {'polkit.message':details}
++        cancel_id = ''
++
++        if False:
++            source=source+'-self'
++
++        logging.info('authentication status: %r.',authentication)
++        if True == authentication:
++            subject = ('system-bus-name', {'name': sender})
++            action = get_policykit_authority_action_enum(source)
++
++            def policykit_done(xxx_todo_changeme):
++                (authorized, challenged, auth_details) = xxx_todo_changeme
++                if authorized:
++                    deferred.callback(auth_details)
++                elif challenged:
++                    deferred.errback(AuthorizationFailed(subject, action))
++                else:
++                    deferred.errback(NotAuthorizedError(subject, action))
++
++            logging.info("PolicyKit source: %s, action: %s.",source,action)
++            kit = dbus.SystemBus().get_object('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority')
++            kit = dbus.Interface(kit, 'org.freedesktop.PolicyKit1.Authority')
++            kit.CheckAuthorization(subject, action, details, 
++                                dbus.UInt32(1), action, 
++                                timeout=60*60*24*7,
++                                reply_handler=policykit_done,
++                                error_handler=deferred.errback)
++        else:
++            deferred.callback(_("Authentication success."))
++    except Exception as e:
++        logging.error(e)
++        deferred.errback(AuthorizationFailed(subject, action))
++    return deferred
++
++def kysec_authority():
++    _allow_kylinsign        = False
++    _verify_kylinsign       = False
++    _kysec_authority_status = True
++
++    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 and "#allow-kylinsign" not in line:
++                    _allow_kylinsign = True
++                if "verify-kylinsign" in line and "#verify-kylinsign" not in line:
++                    _verify_kylinsign = True
++
++            if _allow_kylinsign == True and _verify_kylinsign == False: #策略: 阻止
++                logging.info("unknown sources apply installation policies: deter")
++                _kysec_authority_status = False
++
++            elif _allow_kylinsign == True and _verify_kylinsign == True: #策略: 警告
++                logging.info("unknown sources apply installation policies: warning")
++
++            elif _allow_kylinsign == False and _verify_kylinsign == False: #策略: 关闭
++                logging.info("unknown sources apply installation policies: close")
++                _kysec_authority_status = False
++
++    except Exception as e:
++        logging.error(e)
++
++    return _kysec_authority_status
++
++
++class NotAuthorizedError(dbus.DBusException):
++
++    _dbus_error_name = "org.freedesktop.PolicyKit.Error.NotAuthorized"
++
++    def __init__(self, subject, action_id):
++        dbus.DBusException.__init__(self, "%s: %s" % (subject, action_id))
++        self.action_id = action_id
++        self.subject = subject
++
++
++class AuthorizationFailed(NotAuthorizedError):
++    _dbus_error_name = "org.freedesktop.PolicyKit.Error.Failed"
++
++
++def ApplicationSecInstall(debname = ''):
++
++    SEC_MODE_NORMAL = 0
++    SEC_MODE_WHITELIST = 1
++    SEC_MODE_BLACKLIST = 2
++
++    try:
++        logging.debug("Security Application Install Check .")
++
++        sec = dbus.SystemBus().get_object('com.kylin.kysdk.applicationsec', '/com/kylin/kysdk/applicationsec')
++        secinterface = dbus.Interface(sec, dbus_interface='com.kylin.kysdk.applicationsec.antiinstall')
++        secMode = secinterface.GetMode()
++
++        if SEC_MODE_NORMAL == secMode:
++            logging.info("Application installation control policy not enabled .")
++            return True,_("Application installation control policy not enabled .")
++
++        elif SEC_MODE_WHITELIST == secMode:
++            logging.info("Application installation in whitelist mode .")
++
++            if secinterface.PackageIsInWhilteList(debname) :
++                logging.info("Application in whitelist .")
++                return True,""
++            else:
++                logging.info("Application not in whitelist .")
++                return False,_("Installation failed! Application is not in the software whitelist list!")
++
++        elif SEC_MODE_BLACKLIST == secMode:
++            logging.info("Application installation in blacklist mode .")
++            
++            if secinterface.PackageIsInBlackList(debname) :
++                logging.info("Application in blacklist .")
++                return False,_("Installation failed! Application is in the software blacklist list!") 
++            else:
++                logging.info("Application not in blacklist .")
++                return True,""
++
++        else:
++            logging.info("Application installation in unknown mode .")
++            return True,_("Application installation in unknown mode .")
++
++    except dbus.exceptions.DBusException as e:
++        dbus_error = str(e._dbus_error_name)
++        compare_error = str("org.freedesktop.DBus.Error.ServiceUnknown")
++        if dbus_error == compare_error:
++            logging.info("Application installation control policy not enabled .")
++            return True,"Application installation control policy not enabled ."
++        raise
++
++    except Exception as e:
++        logging.error(e)
++        return False,str(e)
++
++if __name__ == "__main__":
++    #print(mirror_from_sources_list())
++    #print(on_battery())
++    #print(inside_chroot())
++    #print(iptables_active())
++    error(None, "bar", "baz")
+diff --git a/backend-immutable/SystemUpdater/packageManager/pmWorker.py b/backend-immutable/SystemUpdater/packageManager/pmWorker.py
+new file mode 100644
+index 0000000..03c7ba8
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/packageManager/pmWorker.py
+@@ -0,0 +1,201 @@
++#!/usr/bin/env python
++# -*- coding: utf-8 -*-
++
++import logging
++from gettext import gettext as _
++
++from SystemUpdater.packageManager.pmUtils import *
++from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
++from SystemUpdater.packageManager.UpdaterSDKInterface import UpdaterSDKPkgInstall
++
++class PmWorker():
++    def __init__(self, parent = None):
++        self.parent             = parent
++        self.dbus_send          = parent.dbus_send
++        self.sqlite3_server     = parent.sqlite3_server
++        self.updater_package    = UpdaterSDKPkgInstall ( parent )
++
++        if not hasattr(parent, 'configs_uncover') or parent.configs_uncover is None:
++            self.configs_uncover    = UpgradeConfig (
++                                        defaults_conf = "/etc/kylin-system-updater/system-updater-defaults.conf" )
++        else:
++            self.configs_uncover    = parent.configs_uncover
++
++    def start_deb_install(self, deb_uri = "", _check_local_dep = False, _auto_satisfy = False, source = '', sender=None):
++        sender_name = get_proc_from_dbus_name(sender)
++        caller_trans = get_source_name_from_enum(sender_name)
++
++        try:
++            def _run_install_handler():
++                _success = self.updater_package.package_interface_install(deb_uri)
++                if self.updater_package.installFinished:
++                    self.updater_package.installFinished = False
++                else:
++                    self.dbus_send.InstalldebFinished(_success, '', '')
++                    self.dbus_send.InstalldebFinishedWithErrCode(_success, '', '', '')
++
++            def on_authorization_success(result):
++                logging.info("Authorization success ...")
++
++                self.sqlite3_server.deb_policy_keep = True
++                def _check_deb_policy():
++                    if self.sqlite3_server.deb_policy_timestamp % 10 == 0:
++                        logging.info("Checking for deb policy timeout(%d)...",self.sqlite3_server.deb_policy_timestamp)
++                    if (self.sqlite3_server.deb_policy_timestamp <= 0):
++                        logging.warning("Deb policy timeout")
++                        self.sqlite3_server.deb_policy_keep = False
++                        return False
++                    else:
++                        self.sqlite3_server.deb_policy_timestamp = self.sqlite3_server.deb_policy_timestamp - 1
++                    return True
++
++                from gi.repository import GLib
++                self.sqlite3_server.deb_policy_timestamp = 60 * 5
++                GLib.timeout_add_seconds(1,_check_deb_policy)
++
++                _run_install_handler()
++
++            def on_authorization_failure(error):
++                try:
++                    logging.info("Authorization failed ...")
++
++                    self.sqlite3_server.deb_policy_keep = False
++                    self.sqlite3_server.deb_policy_timestamp = 0
++
++                    error.raise_exception()
++                except Exception as error:
++                    logging.error(error)
++                    self.dbus_send.InstalldebFinished(False,_("Cancel authentication."),'')
++                    self.dbus_send.InstalldebFinishedWithErrCode(False,_("Cancel authentication."),'','')
++
++            def _policykit_authority_handler(install_handler = None, authority_failed_handler = None):
++                if not self.sqlite3_server.deb_policy_keep:
++                    deferred = PolicyKit_Authority(caller_trans+_(" requires authentication to install software packages."),
++                                                sender = sender,
++                                                authentication = self.configs_uncover.getWithDefault(
++                                                                                        "InstallAndPurge",
++                                                                                        "install_authority",True),
++                                                source=source)
++
++                    deferred.add_callback(on_authorization_success)
++                    deferred.add_errback(on_authorization_failure)
++                else:
++                    self.sqlite3_server.deb_policy_timestamp = 60 * 5
++                    logging.info("Deb policy keep, ignore...")
++
++                    _run_install_handler()
++
++            if not deb_verify(deb_uri):
++                _policykit_authority_handler()
++            else:
++                _run_install_handler()
++
++        except Exception as e:
++            logging.info("start_deb_install error: %s", e)
++            self.dbus_send.InstalldebFinished(False, str(e), '')
++            self.dbus_send.InstalldebFinishedWithErrCode(False, str(e), '', '')
++
++    def start_purge_pkgs(self,pkgs_list,sender=None):
++        try:
++            sender_name = get_proc_from_dbus_name(sender)
++
++            def _run_purge_handler():
++                for pl in pkgs_list:
++                    _success = self.updater_package.package_interface_remove(pl)
++                    if not _success:
++                        break
++
++                if self.updater_package.purgeFinished:
++                    self.updater_package.purgeFinished = False
++                else:
++                    self.dbus_send.PurgePackagesFinished (_success, '', '')
++                    self.dbus_send.PurgePackagesFinishedWithPkgname (_success, '', '', ",".join(pkgs_list))
++                    self.dbus_send.PurgePackagesFinishedWithErrCode (_success, '', '', ",".join(pkgs_list),
++                                                                    get_error_num_from_enum (SUCCESS_PURGE_PKG))
++
++            def on_authorization_success(result):
++                logging.info("Authorization success ...")
++
++                self.sqlite3_server.purge_policy_keep = True
++                def _check_purge_policy():
++                    if self.sqlite3_server.purge_policy_timestamp % 10 == 0:
++                        logging.info("Checking for deb policy timeout(%d)...",self.sqlite3_server.purge_policy_timestamp)
++                    if (self.sqlite3_server.purge_policy_timestamp <= 0):
++                        logging.warning("Deb policy timeout")
++                        self.sqlite3_server.purge_policy_keep = False
++                        return False
++                    else:
++                        self.sqlite3_server.purge_policy_timestamp = self.sqlite3_server.purge_policy_timestamp - 1
++                    return True
++
++                from gi.repository import GLib
++                self.sqlite3_server.purge_policy_timestamp = 60 * 5
++                GLib.timeout_add_seconds(1,_check_purge_policy)
++
++                _run_purge_handler()
++
++            def on_authorization_failure(error):
++                """Convert the DeferredException to a normal exception."""
++                try:
++                    logging.info("Authorization failed ...")
++
++                    self.sqlite3_server.purge_policy_keep = False
++                    self.sqlite3_server.purge_policy_timestamp = 0
++
++                    error.raise_exception()
++                except Exception as error:
++                    logging.error(error)
++                    self.dbus_send.PurgePackagesFinished(False,_("Cancel authentication."),'')
++                    self.dbus_send.PurgePackagesFinishedWithPkgname(False,_("Cancel authentication."),'',",".join(pkgs_list))
++                    self.dbus_send.PurgePackagesFinishedWithErrCode(False,_("Cancel authentication."),'',",".join(pkgs_list),get_error_num_from_enum(ERROR_PURGE_PKG_VERIFY))
++
++            def _policykit_authority_handler(install_handler = None, authority_failed_handler = None):
++                if not self.sqlite3_server.purge_policy_keep:
++                    deferred = PolicyKit_Authority(
++                                    get_source_name_from_enum(sender_name)+_(" requires authentication to uninstall software packages."),
++                                    sender = sender,
++                                    authentication = self.configs_uncover.getWithDefault("InstallAndPurge","purge_authority",False), 
++                                    source=sender_name)
++
++                    deferred.add_callback(on_authorization_success)
++                    deferred.add_errback(on_authorization_failure)
++                else:
++                    self.sqlite3_server.purge_policy_timestamp = 60 * 5
++                    logging.info("Purge policy keep, ignore...")
++
++                    _run_purge_handler()
++
++            _policykit_authority_handler()
++
++        except Exception as e:
++            logging.error("start_purge_pkgs error: %s", e)
++
++    def start_back_upgrade(self, pkgs_list, sender=None):
++        _success        = False
++
++        try:
++            self.updater_package.batchInstPkgs = [str(item) for item in pkgs_list]
++
++            _success = self.updater_package.package_interface_batch_install(pkgs_list)
++            if self.updater_package.batchInstFinished:
++                self.updater_package.batchInstFinished = False
++            else:
++                self.dbus_send.UpdateInstallFinished(_success, self.updater_package.batchInstPkgs, '', '')
++                self.updater_package.package_interface_install_clear()
++
++        except Exception as e:
++            logging.error("start_back_upgrade err: %s", e)
++
++    def check_package_status(self, _name, _version = '', sender = None):
++        install_status = -100
++
++        try:
++            if not _version:
++                _version = 'NULL'
++
++            install_status = self.updater_package.package_interface_check_status(_name, _version)
++
++        except Exception as e:
++            logging.error("check_package_status err: %s", e)
++
++        return install_status
+diff --git a/backend-immutable/SystemUpdater/pluginbase.py b/backend-immutable/SystemUpdater/pluginbase.py
+new file mode 100644
+index 0000000..0370f17
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/pluginbase.py
+@@ -0,0 +1,449 @@
++# -*- coding: utf-8 -*-
++"""
++    pluginbase
++    ~~~~~~~~~~
++
++    Pluginbase is a module for Python that provides a system for building
++    plugin based applications.
++
++    :copyright: (c) Copyright 2014 by Armin Ronacher.
++    :license: BSD, see LICENSE for more details.
++"""
++import os
++import sys
++import uuid
++import errno
++import pkgutil
++import hashlib
++import threading
++
++from types import ModuleType
++from weakref import ref as weakref
++
++
++PY2 = sys.version_info[0] == 2
++if PY2:
++    text_type = unicode
++    string_types = (unicode, str)
++    from cStringIO import StringIO as NativeBytesIO
++else:
++    text_type = str
++    string_types = (str,)
++    from io import BytesIO as NativeBytesIO
++
++
++__version__ = '1.0.1'
++_local = threading.local()
++
++_internalspace = ModuleType(__name__ + '._internalspace')
++_internalspace.__path__ = []
++sys.modules[_internalspace.__name__] = _internalspace
++
++
++def get_plugin_source(module=None, stacklevel=None):
++    """Returns the :class:`PluginSource` for the current module or the given
++    module.  The module can be provided by name (in which case an import
++    will be attempted) or as a module object.
++
++    If no plugin source can be discovered, the return value from this method
++    is `None`.
++
++    This function can be very useful if additional data has been attached
++    to the plugin source.  For instance this could allow plugins to get
++    access to a back reference to the application that created them.
++
++    :param module: optionally the module to locate the plugin source of.
++    :param stacklevel: defines how many levels up the module should search
++                       for before it discovers the plugin frame.  The
++                       default is 0.  This can be useful for writing wrappers
++                       around this function.
++    """
++    if module is None:
++        frm = sys._getframe((stacklevel or 0) + 1)
++        name = frm.f_globals['__name__']
++        glob = frm.f_globals
++    elif isinstance(module, string_types):
++        frm = sys._getframe(1)
++        name = module
++        glob = __import__(module, frm.f_globals,
++                          frm.f_locals, ['__dict__']).__dict__
++    else:
++        name = module.__name__
++        glob = module.__dict__
++    return _discover_space(name, glob)
++
++
++def get_searchpath(path, depth=float('inf'), followlinks=False):
++    """This utility function returns a list directories suitable for use as the
++    *searchpath* argument to :class:`PluginSource`. This will recursively add
++    directories up to the specified depth.
++
++    :param str path: The directory on the file system to start the search path
++                     at. It will be included in the result.
++    :param int depth: The number of directories to recurse into while building
++                      the search path. By default the function will iterate into
++                      all child directories.
++    :param bool followlinks: Whether or not to recurse into directories which
++                             are symbolic links.
++    :return: A list of directories, including *path* and child directories.
++    :rtype: list
++    """
++    # os.walk implements a depth-first approach which results in unnecessarily
++    # slow execution when *path* is a large tree and *depth* is a small number
++    paths = [path]
++    for dir_entry in os.listdir(path):
++        sub_path = os.path.join(path, dir_entry)
++        if not os.path.isdir(sub_path):
++            continue
++        if not followlinks and os.path.islink(sub_path):
++            continue
++        if depth:
++            paths.extend(get_searchpath(sub_path, depth - 1, followlinks))
++    return paths
++
++
++def _discover_space(name, globals):
++    try:
++        return _local.space_stack[-1]
++    except (AttributeError, IndexError):
++        pass
++
++    if '__pluginbase_state__' in globals:
++        return globals['__pluginbase_state__'].source
++
++    mod_name = globals.get('__name__')
++    if mod_name is not None and \
++       mod_name.startswith(_internalspace.__name__ + '.'):
++        end = mod_name.find('.', len(_internalspace.__name__) + 1)
++        space = sys.modules.get(mod_name[:end])
++        if space is not None:
++            return space.__pluginbase_state__.source
++
++
++def _shutdown_module(mod):
++    members = list(mod.__dict__.items())
++    for key, value in members:
++        if key[:1] != '_':
++            setattr(mod, key, None)
++    for key, value in members:
++        setattr(mod, key, None)
++
++
++def _to_bytes(s):
++    if isinstance(s, text_type):
++        return s.encode('utf-8')
++    return s
++
++
++class _IntentionallyEmptyModule(ModuleType):
++
++    def __getattr__(self, name):
++        try:
++            return ModuleType.__getattr__(self, name)
++        except AttributeError:
++            if name[:2] == '__':
++                raise
++            raise RuntimeError(
++                'Attempted to import from a plugin base module (%s) without '
++                'having a plugin source activated.  To solve this error '
++                'you have to move the import into a "with" block of the '
++                'associated plugin source.' % self.__name__)
++
++
++class _PluginSourceModule(ModuleType):
++
++    def __init__(self, source):
++        modname = '%s.%s' % (_internalspace.__name__, source.spaceid)
++        ModuleType.__init__(self, modname)
++        self.__pluginbase_state__ = PluginBaseState(source)
++
++    @property
++    def __path__(self):
++        try:
++            ps = self.__pluginbase_state__.source
++        except AttributeError:
++            return []
++        return ps.searchpath + ps.base.searchpath
++
++
++def _setup_base_package(module_name):
++    try:
++        mod = __import__(module_name, None, None, ['__name__'])
++    except ImportError:
++        mod = None
++        if '.' in module_name:
++            parent_mod = __import__(module_name.rsplit('.', 1)[0],
++                                    None, None, ['__name__'])
++        else:
++            parent_mod = None
++
++    if mod is None:
++        mod = _IntentionallyEmptyModule(module_name)
++        if parent_mod is not None:
++            setattr(parent_mod, module_name.rsplit('.', 1)[-1], mod)
++        sys.modules[module_name] = mod
++
++
++class PluginBase(object):
++    """The plugin base acts as a control object around a dummy Python
++    package that acts as a container for plugins.  Usually each
++    application creates exactly one base object for all plugins.
++
++    :param package: the name of the package that acts as the plugin base.
++                    Usually this module does not exist.  Unless you know
++                    what you are doing you should not create this module
++                    on the file system.
++    :param searchpath: optionally a shared search path for modules that
++                       will be used by all plugin sources registered.
++    """
++
++    def __init__(self, package, searchpath=None):
++        #: the name of the dummy package.
++        self.package = package
++        if searchpath is None:
++            searchpath = []
++        #: the default search path shared by all plugins as list.
++        self.searchpath = searchpath
++        _setup_base_package(package)
++
++    def make_plugin_source(self, *args, **kwargs):
++        """Creates a plugin source for this plugin base and returns it.
++        All parameters are forwarded to :class:`PluginSource`.
++        """
++        return PluginSource(self, *args, **kwargs)
++
++
++class PluginSource(object):
++    """The plugin source is what ultimately decides where plugins are
++    loaded from.  Plugin bases can have multiple plugin sources which act
++    as isolation layer.  While this is not a security system it generally
++    is not possible for plugins from different sources to accidentally
++    cross talk.
++
++    Once a plugin source has been created it can be used in a ``with``
++    statement to change the behavior of the ``import`` statement in the
++    block to define which source to load the plugins from::
++
++        plugin_source = plugin_base.make_plugin_source(
++            searchpath=['./path/to/plugins', './path/to/more/plugins'])
++
++        with plugin_source:
++            from myapplication.plugins import my_plugin
++
++    :param base: the base this plugin source belongs to.
++    :param identifier: optionally a stable identifier.  If it's not defined
++                       a random identifier is picked.  It's useful to set this
++                       to a stable value to have consistent tracebacks
++                       between restarts and to support pickle.
++    :param searchpath: a list of paths where plugins are looked for.
++    :param persist: optionally this can be set to `True` and the plugins
++                    will not be cleaned up when the plugin source gets
++                    garbage collected.
++    """
++    # Set these here to false by default so that a completely failing
++    # constructor does not fuck up the destructor.
++    persist = False
++    mod = None
++
++    def __init__(self, base, identifier=None, searchpath=None,
++                 persist=False):
++        #: indicates if this plugin source persists or not.
++        self.persist = persist
++        if identifier is None:
++            identifier = str(uuid.uuid4())
++        #: the identifier for this source.
++        self.identifier = identifier
++        #: A reference to the plugin base that created this source.
++        self.base = base
++        #: a list of paths where plugins are searched in.
++        self.searchpath = searchpath
++        #: The internal module name of the plugin source as it appears
++        #: in the :mod:`pluginsource._internalspace`.
++        self.spaceid = '_sp' + hashlib.md5(
++            _to_bytes(self.base.package) + b'|' +
++            _to_bytes(identifier),
++        ).hexdigest()
++        #: a reference to the module on the internal
++        #: :mod:`pluginsource._internalspace`.
++        self.mod = _PluginSourceModule(self)
++
++        if hasattr(_internalspace, self.spaceid):
++            raise RuntimeError('This plugin source already exists.')
++        sys.modules[self.mod.__name__] = self.mod
++        setattr(_internalspace, self.spaceid, self.mod)
++
++    def __del__(self):
++        if not self.persist:
++            self.cleanup()
++
++    def list_plugins(self):
++        """Returns a sorted list of all plugins that are available in this
++        plugin source.  This can be useful to automatically discover plugins
++        that are available and is usually used together with
++        :meth:`load_plugin`.
++        """
++        rv = []
++        for _, modname, ispkg in pkgutil.iter_modules(self.mod.__path__):
++            rv.append(modname)
++        return sorted(rv)
++
++    def load_plugin(self, name):
++        """This automatically loads a plugin by the given name from the
++        current source and returns the module.  This is a convenient
++        alternative to the import statement and saves you from invoking
++        ``__import__`` or a similar function yourself.
++
++        :param name: the name of the plugin to load.
++        """
++        if '.' in name:
++            raise ImportError('Plugin names cannot contain dots.')
++        with self:
++            return __import__(self.base.package + '.' + name,
++                              globals(), {}, ['__name__'])
++
++    def open_resource(self, plugin, filename):
++        """This function locates a resource inside the plugin and returns
++        a byte stream to the contents of it.  If the resource cannot be
++        loaded an :exc:`IOError` will be raised.  Only plugins that are
++        real Python packages can contain resources.  Plain old Python
++        modules do not allow this for obvious reasons.
++
++        .. versionadded:: 0.3
++
++        :param plugin: the name of the plugin to open the resource of.
++        :param filename: the name of the file within the plugin to open.
++        """
++        mod = self.load_plugin(plugin)
++        fn = getattr(mod, '__file__', None)
++        if fn is not None:
++            if fn.endswith(('.pyc', '.pyo')):
++                fn = fn[:-1]
++            if os.path.isfile(fn):
++                return open(os.path.join(os.path.dirname(fn), filename), 'rb')
++        buf = pkgutil.get_data(self.mod.__name__ + '.' + plugin, filename)
++        if buf is None:
++            raise IOError(errno.ENOENT, 'Could not find resource')
++        return NativeBytesIO(buf)
++
++    def cleanup(self):
++        """Cleans up all loaded plugins manually.  This is necessary to
++        call only if :attr:`persist` is enabled.  Otherwise this happens
++        automatically when the source gets garbage collected.
++        """
++        self.__cleanup()
++
++    def __cleanup(self, _sys=sys, _shutdown_module=_shutdown_module):
++        # The default parameters are necessary because this can be fired
++        # from the destructor and so late when the interpreter shuts down
++        # that these functions and modules might be gone.
++        if self.mod is None or self.mod.__name__ is None:
++            return
++        modname = self.mod.__name__
++        self.mod.__pluginbase_state__ = None
++        self.mod = None
++        try:
++            delattr(_internalspace, self.spaceid)
++        except AttributeError:
++            pass
++        prefix = modname + '.'
++        # avoid the bug described in issue #6
++        if modname in _sys.modules:
++            del _sys.modules[modname]
++        for key, value in list(_sys.modules.items()):
++            if not key.startswith(prefix):
++                continue
++            mod = _sys.modules.pop(key, None)
++            if mod is None:
++                continue
++            _shutdown_module(mod)
++
++    def __assert_not_cleaned_up(self):
++        if self.mod is None:
++            raise RuntimeError('The plugin source was already cleaned up.')
++
++    def __enter__(self):
++        self.__assert_not_cleaned_up()
++        _local.__dict__.setdefault('space_stack', []).append(self)
++        return self
++
++    def __exit__(self, exc_type, exc_value, tb):
++        try:
++            _local.space_stack.pop()
++        except (AttributeError, IndexError):
++            pass
++
++    def _rewrite_module_path(self, modname):
++        self.__assert_not_cleaned_up()
++        if modname == self.base.package:
++            return self.mod.__name__
++        elif modname.startswith(self.base.package + '.'):
++            pieces = modname.split('.')
++            return self.mod.__name__ + '.' + '.'.join(
++                pieces[self.base.package.count('.') + 1:])
++
++
++class PluginBaseState(object):
++    __slots__ = ('_source',)
++
++    def __init__(self, source):
++        if source.persist:
++            self._source = lambda: source
++        else:
++            self._source = weakref(source)
++
++    @property
++    def source(self):
++        rv = self._source()
++        if rv is None:
++            raise AttributeError('Plugin source went away')
++        return rv
++
++
++class _ImportHook(ModuleType):
++
++    def __init__(self, name, system_import):
++        ModuleType.__init__(self, name)
++        self._system_import = system_import
++        self.enabled = True
++
++    def enable(self):
++        """Enables the import hook which drives the plugin base system.
++        This is the default.
++        """
++        self.enabled = True
++
++    def disable(self):
++        """Disables the import hook and restores the default import system
++        behavior.  This effectively breaks pluginbase but can be useful
++        for testing purposes.
++        """
++        self.enabled = False
++
++    def plugin_import(self, name, globals=None, locals=None,
++                      fromlist=None, level=None):
++        if level is None:
++            # set the level to the default value specific to this python version
++            level = -1 if PY2 else 0
++        import_name = name
++        if self.enabled:
++            ref_globals = globals
++            if ref_globals is None:
++                ref_globals = sys._getframe(1).f_globals
++            space = _discover_space(name, ref_globals)
++            if space is not None:
++                actual_name = space._rewrite_module_path(name)
++                if actual_name is not None:
++                    import_name = actual_name
++
++        return self._system_import(import_name, globals, locals,
++                                   fromlist, level)
++
++
++try:
++    import __builtin__ as builtins
++except ImportError:
++    import builtins
++import_hook = _ImportHook(__name__ + '.import_hook', builtins.__import__)
++builtins.__import__ = import_hook.plugin_import
++sys.modules[import_hook.__name__] = import_hook
++del builtins
+diff --git a/backend-immutable/SystemUpdater/plugins/update/randomstr.py b/backend-immutable/SystemUpdater/plugins/update/randomstr.py
+new file mode 100644
+index 0000000..268b4c1
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/plugins/update/randomstr.py
+@@ -0,0 +1,11 @@
++import random
++import string
++import logging
++
++def make_random(parent,trans):
++    logging.info("Processing transaction")
++    logging.info("%sdddddddddddddd",trans.sender)
++    return trans
++
++def setup(app):
++    app.register_formatter('random', make_random)
+diff --git a/backend-immutable/SystemUpdater/push_update.py b/backend-immutable/SystemUpdater/push_update.py
+new file mode 100644
+index 0000000..d4b006d
+--- /dev/null
++++ b/backend-immutable/SystemUpdater/push_update.py
+@@ -0,0 +1,83 @@
++import logging
++import dbus
++from dataclasses import dataclass
++from .Core.errors import *
++from .Core.enums import *
++from SystemUpdater.constants import PUTSH_CONTENT_LOCATION,DEFAULT_REPO_NAME
++from gettext import gettext as _
++
++@dataclass
++class UpdateContent:
++    repo_name: str = DEFAULT_REPO_NAME
++    branch: str = None
++    revision: str = None
++
++#更新important.list的本次升级的列表
++def update_important(bus,reply_handler,error_handler):
++    def _update_important_reply(retval):
++        if bool(retval) == False:
++            error_handler(ERROR_UPDATE_SOURCE_FAILED)
++        else:
++            push_content = _get_push_content()
++            reply_handler(push_content)
++    def _update_important_error(retval):
++        logging.error(str(retval))
++        error_handler(ERROR_UPDATE_SOURCE_FAILED)
++    
++    try:
++        obj = bus.get_object('com.kylin.software.properties', '/com/kylin/software/properties')
++
++        interface = dbus.Interface(obj, dbus_interface='com.kylin.software.properties.interface')
++        interface.updateSourceTemplate(timeout=20,reply_handler=_update_important_reply,error_handler=_update_important_error)
++    except Exception as e:
++        logging.warning(str(e))
++        raise UpdateBaseError(ERROR_UPDATE_SOURCE_FAILED)
++
++def _read_important_data():
++    # 当存在源管理推送内容时 优先从源管理获取当前推送的分支信息 
++    try:
++        push_list = []
++        with open(PUTSH_CONTENT_LOCATION, 'r') as f:
++            data = f.read()
++            push_list = data.split()
++
++        #去除重复内容
++        push_list = list(set(push_list))
++
++        logging.info("Server push list: %r",push_list)
++        return push_list
++    except Exception as e:
++        logging.warning(str(e))
++        return []
++
++def _parse_push_content(push_content):
++    # 推送的内容格式:
++    # 1、带有commit号时拉取分支指定commit,仓库名称:分支名称@commit号 示例:kylin:kylin/desktop/v11/2503/xc/general/all/beta2/amd64@e46fb4558c5e0d2724af
++    # 2、不带有commit号时拉取分支最新commit,kylin:kylin/2203/230  示例:kylin:kylin/desktop/v11/2503/xc/general/all/beta2/amd64
++    update_content = UpdateContent()
++    try:
++        refspec = push_content.split(":")
++        if len(refspec) == 2:
++            update_content.repo_name = refspec[0]
++            ref_and_rev = refspec[1]
++            if "@" in ref_and_rev:
++                refs_details = ref_and_rev.split("@")
++                update_content.branch = refs_details[0]
++                update_content.revision = refs_details[1]
++            else:
++                update_content.branch = ref_and_rev
++            return [update_content]
++        else:
++            logging.error("Push updates do not contain the repo name...")
++            return []
++    except Exception as e:
++        logging.warning(str(e))
++        return []
++
++def _get_push_content():
++    update_list = []
++    push_list = _read_important_data()
++    for cont in push_list:
++        update_cont = _parse_push_content(cont)
++        update_list = update_cont + update_list
++    return update_list
+diff --git a/backend-immutable/data/com.kylin.UpgradeStrategies.limit b/backend-immutable/data/com.kylin.UpgradeStrategies.limit
+new file mode 100644
+index 0000000..148dccd
+--- /dev/null
++++ b/backend-immutable/data/com.kylin.UpgradeStrategies.limit
+@@ -0,0 +1,33 @@
++[whitelist]
++key1 = /usr/bin/kylin-background-upgrade
++key2 = /usr/bin/ukui-control-center
++key3 = /usr/bin/kylin-installer
++key4 = /usr/bin/kylin-uninstaller
++key5 = /usr/bin/kylin-software-properties-service
++key6 = /usr/bin/kylin-source-update
++key7 = /usr/bin/kylin-source-manager
++key8 = /usr/bin/kylin-unattended-upgrade
++key9 = /usr/bin/kylin-software-center
++key10 = /usr/bin/kylin-printer
++key11 = /usr/bin/kylin-printer-applet
++key12 = /usr/bin/hedron-client
++key13 = /usr/bin/kylin-software-center-plugin-synchrodata
++key14 = /usr/share/kylin-system-updater/kylin-system-updater
++key15 = /usr/bin/kylin-updateresult-notify-new
++key16 = /usr/bin/ukui-menu
++key17 = /usr/bin/ukui-session
++key18 = /usr/bin/NotifySend
++key19 = /usr/bin/kylin-scanner
++key20 = /usr/bin/kylin-os-manager
++key21 = /usr/sbin/ksc-scan-daemon
++key22 = /usr/sbin/preinstall-daemon
++key23 = /usr/bin/ukui-session-tools
++key24 = /usr/bin/kylin-unattended-upgrade-shutdown
++key25 = /usr/sbin/kimcd
++key26 = /usr/bin/hedron-domain-hook.py
++key27 = /usr/bin/NotifySend (deleted)
++key28 = /usr/bin/kylin-updatefinish-notify-new
++key29 = /usr/bin/UpgradeRebootNotify
++key30 = /usr/bin/peony-qt-desktop
++key31 = /usr/bin/ukui-panel
++key32 = /usr/bin/kylin-police
+\ No newline at end of file
+diff --git a/backend-immutable/data/com.kylin.UpgradeStrategies.limit.verify b/backend-immutable/data/com.kylin.UpgradeStrategies.limit.verify
+new file mode 100644
+index 0000000..1666589
+--- /dev/null
++++ b/backend-immutable/data/com.kylin.UpgradeStrategies.limit.verify
+@@ -0,0 +1 @@
++7fa6c5b19ae662c3221d42ef41193e90bffd6a34
+\ No newline at end of file
+diff --git a/backend-immutable/data/settings-default.json b/backend-immutable/data/settings-default.json
+new file mode 100644
+index 0000000..28036d1
+--- /dev/null
++++ b/backend-immutable/data/settings-default.json
+@@ -0,0 +1,3 @@
++{
++  "status": "none"
++}
+\ No newline at end of file
+diff --git a/backend-immutable/kylin-system-updater b/backend-immutable/kylin-system-updater
+index 607ba04..baf60ca 100755
+--- a/backend-immutable/kylin-system-updater
++++ b/backend-immutable/kylin-system-updater
+@@ -10,16 +10,15 @@ import signal
+ import os
+ import sys
+ import gettext
+-
++from SystemUpdater.configs import settings
+ from SystemUpdater.Core.LogManager import get_logfile as logfile
+-
++from SystemUpdater.constants import DEFAULT_OS_NAME
+ gettext.bindtextdomain('kylin-system-updater', '/usr/share/locale')
+ gettext.textdomain('kylin-system-updater')
+ _ = gettext.gettext
+ 
+ #定义日志的格式 
+ FORMAT = "%(asctime)s [%(levelname)s]: %(message)s"
+-
+ FORMAT_DEBUG = '%(asctime)-15s %(levelname)s(%(filename)s:%(lineno)d):%(message)s'
+ 
+ def signal_handler_term(signal, frame):
+@@ -40,13 +39,16 @@ if __name__ == "__main__":
+   parser.add_option("", "--sysroot", default=None,
+                       action="store", type="string", dest="sysroot",
+                       help=_("Import sysroot path in the given path"))
+-  parser.add_option("", "--os", default=None,
++  parser.add_option("", "--os", default=DEFAULT_OS_NAME,
+                       action="store", type="string", dest="os",
+                       help=_("Import os name in the given string"))
+   parser.add_option("-p", "--prohibit-shutdown",
+                     default=False,
+                     action="store_true", dest="prohibit_shutdown",
+                     help=_("close auto shutdown"))
++  parser.add_option ("-n","--no-update-source", action="store_false",
++                    dest="update_source", default=True,
++                    help=_("Do not check for updates source when updating"))
+   parser.add_option("--no-check-network",
+                     default=True,
+                     action="store_false", dest="check_network",
+@@ -54,6 +56,9 @@ if __name__ == "__main__":
+ 
+   (options, args) = parser.parse_args()
+ 
++  # 将命令行参数 加载到settings的配置项中
++  settings.update(vars(options))
++
+   if os.getuid() != 0:
+       print(_("You need to be root to run this application"))
+       sys.exit(1)
+diff --git a/backend-immutable/kylin-upgrade-strategies b/backend-immutable/kylin-upgrade-strategies
+index a343f46..c60e461 100755
+--- a/backend-immutable/kylin-upgrade-strategies
++++ b/backend-immutable/kylin-upgrade-strategies
+@@ -25,7 +25,7 @@ FORMAT_DEBUG = '%(asctime)-15s %(levelname)s(%(filename)s:%(lineno)d):%(message)
+ def signal_handler_term(signal, frame):
+     # type: (int, object) -> None
+     logging.warning("SIGTERM received, will stop")
+-    app.dbusController.Quit(None)
++    app.dbus_send.Quit(None)
+ 
+ if __name__ == "__main__":
+   # Begin parsing of options
+diff --git a/backend-immutable/po/bo_CN.po b/backend-immutable/po/bo_CN.po
+index c945e0c..be65457 100644
+--- a/backend-immutable/po/bo_CN.po
++++ b/backend-immutable/po/bo_CN.po
+@@ -236,3 +236,7 @@ msgstr "སྒྲིག་སྦྱོར་ཕམ་པ། མཉེན་ཆ
+ 
+ msgid "Application installation in unknown mode ."
+ msgstr "ཉེར་སྤྱོད་སྒྲིག་སྦྱོར་དང་དོ་དམ་ཚོད་འཛིན་གྱི་ཐབས་ཇུས་མི་ཤེས་པ།"
++
++#: ../SystemUpdater/Core/utils.py:753
++msgid "Cancel authentication."
++msgstr "ཕྱིར་འབུད་བྱ་རྒྱུ།"
+diff --git a/backend-immutable/po/zh_CN.po b/backend-immutable/po/zh_CN.po
+index 0e0faa1..9a401f2 100644
+--- a/backend-immutable/po/zh_CN.po
++++ b/backend-immutable/po/zh_CN.po
+@@ -2795,8 +2795,6 @@ msgstr "安装失败!软件包在黑名单列表!"
+ msgid "Application installation in unknown mode ."
+ msgstr "应用安装管控策略未知."
+ 
+-
+-
+ msgid "Other tasks are being updated and upgraded, please try again later."
+ msgstr "其他任务正在更新升级中,请稍后再试"
+ 
+@@ -2807,4 +2805,17 @@ msgid "There is no way to rollback to the previous version, there is nothing to
+ msgstr "无法回滚到上一个版本,没有可回滚内容。"
+ 
+ msgid "Check for update exceptions! Please verify that the system deployment is complete."
+-msgstr "检查更新异常!请检查系统部署是否完整。"
+\ No newline at end of file
++msgstr "检查更新异常!请检查系统部署是否完整。"
++
++msgid "Update push is abnormal, and the corresponding branch information cannot be found on the server."
++msgstr "更新推送异常,未在服务端找到相应分支信息。"
++
++msgid "Name of the repository deployed by the current system is empty."
++msgstr "更新检查异常,当前系统部署分支仓库所属信息为空。"
++
++#: ../SystemUpdater/Core/utils.py:753
++msgid "Cancel authentication."
++msgstr "取消认证"
++
++msgid "System upgrade error"
++msgstr "系统更新异常"
+diff --git a/backend-immutable/po/zh_HK.po b/backend-immutable/po/zh_HK.po
+index 0ff5ead..4b147fd 100644
+--- a/backend-immutable/po/zh_HK.po
++++ b/backend-immutable/po/zh_HK.po
+@@ -2706,3 +2706,7 @@ msgstr "安裝失敗!軟件包在黑名單列表!"
+ 
+ msgid "Application installation in unknown mode ."
+ msgstr "應用安裝管控策略未知."
++
++#: ../SystemUpdater/Core/utils.py:753
++msgid "Cancel authentication."
++msgstr "取消認證"
+diff --git a/backend-immutable/po/zh_TW.po b/backend-immutable/po/zh_TW.po
+index 2a55e08..412d059 100644
+--- a/backend-immutable/po/zh_TW.po
++++ b/backend-immutable/po/zh_TW.po
+@@ -2738,3 +2738,7 @@ msgstr "安裝失敗!軟件包在黑名單列表!"
+ 
+ msgid "Application installation in unknown mode ."
+ msgstr "應用安裝管控策略未知."
++
++#: ../SystemUpdater/Core/utils.py:753
++msgid "Cancel authentication."
++msgstr "取消認證"
+diff --git a/backend-immutable/tests/data/cn.kylinos.KylinSystemUpdater.policy b/backend-immutable/tests/data/cn.kylinos.KylinSystemUpdater.policy
+new file mode 100644
+index 0000000..2195a39
+--- /dev/null
++++ b/backend-immutable/tests/data/cn.kylinos.KylinSystemUpdater.policy
+@@ -0,0 +1,129 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<!DOCTYPE policyconfig PUBLIC
++ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
++ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
++<policyconfig>
++
++  <vendor>Kylin System Updater</vendor>
++  <vendor_url>www.kylinos.cn</vendor_url>
++  <icon_name>kylin-system-updater</icon_name>
++
++  <!--Kylin Installer Config-->
++  <action id="cn.kylin.installer.action">
++    <_description>
++      Configuration items added for Kirin Installer
++    </_description>
++    <_message>
++      To Change the settings, you need to authenticate.
++    </_message>
++    <defaults>
++      <allow_any>auth_admin_keep</allow_any>
++      <allow_inactive>auth_admin_keep</allow_inactive>
++      <allow_active>auth_admin_keep</allow_active>
++    </defaults>
++  </action>
++
++  <action id="cn.kylin.uninstaller.action">
++    <_description>
++      Configuration items added for Kirin Uninstaller
++    </_description>
++    <_message>
++      To Change the settings, you need to authenticate.
++    </_message>
++    <defaults>
++      <allow_any>auth_admin_keep</allow_any>
++      <allow_inactive>auth_admin_keep</allow_inactive>
++      <allow_active>auth_admin_keep</allow_active>
++    </defaults>
++  </action>
++
++  <!--Kylin System Updater Config-->
++  <action id="cn.kylinos.KylinSystemUpdater.action">
++    <_description>
++      Configuration items added for Kirin Installer
++    </_description>
++    <_message>
++      To Change the settings, you need to authenticate.
++    </_message>
++    <defaults>
++      <allow_any>auth_admin_keep</allow_any>
++      <allow_inactive>auth_admin_keep</allow_inactive>
++      <allow_active>auth_admin_keep</allow_active>
++    </defaults>
++  </action>
++
++  <!--Kylin Software Center Config-->
++  <action id="cn.kylin.software.center.action">
++    <_description>
++      Configuration items added for Kylin Software Center
++    </_description>
++    <_message>
++      To Change the settings, you need to authenticate.
++    </_message>
++    <defaults>
++      <allow_any>auth_admin_keep</allow_any>
++      <allow_inactive>auth_admin_keep</allow_inactive>
++      <allow_active>auth_admin_keep</allow_active>
++    </defaults>
++  </action>
++
++  <!--Kylin Installer Config-->
++  <action id="cn.kylin.installer.self.action">
++    <_description>
++      Configuration items added for Kirin Installer
++    </_description>
++    <_message>
++      To Change the settings, you need to authenticate.
++    </_message>
++    <defaults>
++      <allow_any>auth_self_keep</allow_any>
++      <allow_inactive>auth_self_keep</allow_inactive>
++      <allow_active>auth_self_keep</allow_active>
++    </defaults>
++  </action>
++
++  <action id="cn.kylin.uninstaller.self.action">
++    <_description>
++      Configuration items added for Kirin Uninstaller
++    </_description>
++    <_message>
++      To Change the settings, you need to authenticate.
++    </_message>
++    <defaults>
++      <allow_any>auth_self_keep</allow_any>
++      <allow_inactive>auth_self_keep</allow_inactive>
++      <allow_active>auth_self_keep</allow_active>
++    </defaults>
++  </action>
++
++  <!--Kylin System Updater Config-->
++  <action id="cn.kylinos.KylinSystemUpdater.self.action">
++    <_description>
++      Configuration items added for Kirin Installer
++    </_description>
++    <_message>
++      To Change the settings, you need to authenticate.
++    </_message>
++    <defaults>
++      <allow_any>auth_self_keep</allow_any>
++      <allow_inactive>auth_self_keep</allow_inactive>
++      <allow_active>auth_self_keep</allow_active>
++    </defaults>
++  </action>
++
++  <!--Kylin Software Center Config-->
++  <action id="cn.kylin.software.center.self.action">
++    <_description>
++      Configuration items added for Kylin Software Center
++    </_description>
++    <_message>
++      To Change the settings, you need to authenticate.
++    </_message>
++    <defaults>
++      <allow_any>auth_self_keep</allow_any>
++      <allow_inactive>auth_self_keep</allow_inactive>
++      <allow_active>auth_self_keep</allow_active>
++    </defaults>
++  </action>
++
++</policyconfig>
+diff --git a/backend-immutable/tests/data/cn.kylinos.UpgradeStrategies.policy b/backend-immutable/tests/data/cn.kylinos.UpgradeStrategies.policy
+new file mode 100644
+index 0000000..debbe26
+--- /dev/null
++++ b/backend-immutable/tests/data/cn.kylinos.UpgradeStrategies.policy
+@@ -0,0 +1,25 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<!DOCTYPE policyconfig PUBLIC
++ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
++ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
++<policyconfig>
++
++  <vendor>Kylin System Updater Config Manager</vendor>
++  <vendor_url>www.kylinos.cn</vendor_url>
++  <icon_name>kylin-upgrade-strategies</icon_name>
++
++  <action id="com.kylin.UpgradeStrategies.action">
++    <_description>
++      system level settings
++    </_description>
++    <_message>
++      To Change the settings, you need to authenticate.
++    </_message>
++    <defaults>
++      <allow_any>auth_admin_keep</allow_any>
++      <allow_inactive>auth_admin_keep</allow_inactive>
++      <allow_active>auth_admin_keep</allow_active>
++    </defaults>
++  </action>
++
++</policyconfig>
+diff --git a/backend-immutable/tests/data/com.kylin.UpgradeStrategies.conf b/backend-immutable/tests/data/com.kylin.UpgradeStrategies.conf
+new file mode 100644
+index 0000000..9142c8c
+--- /dev/null
++++ b/backend-immutable/tests/data/com.kylin.UpgradeStrategies.conf
+@@ -0,0 +1,23 @@
++<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
++
++<!DOCTYPE busconfig PUBLIC
++ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
++ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
++<busconfig>
++    <!-- Only root can own the service -->
++    <policy user="root">
++        <allow own="com.kylin.UpgradeStrategies"/>
++        <allow send_interface="com.kylin.UpgradeStrategies.interface"/>
++    </policy>
++    
++    <!-- Allow anyone to invoke methods on the interfaces -->
++    <policy context="default">
++        <allow send_destination="com.kylin.UpgradeStrategies"
++           send_interface="com.kylin.UpgradeStrategies.interface"/>
++        <allow send_destination="com.kylin.UpgradeStrategies"
++           send_interface="org.freedesktop.DBus.Introspectable"/>
++        <allow send_destination="com.kylin.UpgradeStrategies"
++           send_interface="org.freedesktop.DBus.Properties"/>
++
++    </policy>
++</busconfig>
+diff --git a/backend-immutable/tests/data/com.kylin.UpgradeStrategies.limit b/backend-immutable/tests/data/com.kylin.UpgradeStrategies.limit
+new file mode 100644
+index 0000000..148dccd
+--- /dev/null
++++ b/backend-immutable/tests/data/com.kylin.UpgradeStrategies.limit
+@@ -0,0 +1,33 @@
++[whitelist]
++key1 = /usr/bin/kylin-background-upgrade
++key2 = /usr/bin/ukui-control-center
++key3 = /usr/bin/kylin-installer
++key4 = /usr/bin/kylin-uninstaller
++key5 = /usr/bin/kylin-software-properties-service
++key6 = /usr/bin/kylin-source-update
++key7 = /usr/bin/kylin-source-manager
++key8 = /usr/bin/kylin-unattended-upgrade
++key9 = /usr/bin/kylin-software-center
++key10 = /usr/bin/kylin-printer
++key11 = /usr/bin/kylin-printer-applet
++key12 = /usr/bin/hedron-client
++key13 = /usr/bin/kylin-software-center-plugin-synchrodata
++key14 = /usr/share/kylin-system-updater/kylin-system-updater
++key15 = /usr/bin/kylin-updateresult-notify-new
++key16 = /usr/bin/ukui-menu
++key17 = /usr/bin/ukui-session
++key18 = /usr/bin/NotifySend
++key19 = /usr/bin/kylin-scanner
++key20 = /usr/bin/kylin-os-manager
++key21 = /usr/sbin/ksc-scan-daemon
++key22 = /usr/sbin/preinstall-daemon
++key23 = /usr/bin/ukui-session-tools
++key24 = /usr/bin/kylin-unattended-upgrade-shutdown
++key25 = /usr/sbin/kimcd
++key26 = /usr/bin/hedron-domain-hook.py
++key27 = /usr/bin/NotifySend (deleted)
++key28 = /usr/bin/kylin-updatefinish-notify-new
++key29 = /usr/bin/UpgradeRebootNotify
++key30 = /usr/bin/peony-qt-desktop
++key31 = /usr/bin/ukui-panel
++key32 = /usr/bin/kylin-police
+\ No newline at end of file
+diff --git a/backend-immutable/tests/data/com.kylin.UpgradeStrategies.limit.verify b/backend-immutable/tests/data/com.kylin.UpgradeStrategies.limit.verify
+new file mode 100644
+index 0000000..1666589
+--- /dev/null
++++ b/backend-immutable/tests/data/com.kylin.UpgradeStrategies.limit.verify
+@@ -0,0 +1 @@
++7fa6c5b19ae662c3221d42ef41193e90bffd6a34
+\ No newline at end of file
+diff --git a/backend-immutable/tests/data/com.kylin.UpgradeStrategies.service b/backend-immutable/tests/data/com.kylin.UpgradeStrategies.service
+new file mode 100644
+index 0000000..7d913e8
+--- /dev/null
++++ b/backend-immutable/tests/data/com.kylin.UpgradeStrategies.service
+@@ -0,0 +1,4 @@
++[D-BUS Service]
++Name=com.kylin.UpgradeStrategies
++Exec=/usr/share/kylin-system-updater/kylin-upgrade-strategies
++User=root
+\ No newline at end of file
+diff --git a/backend-immutable/tests/data/com.kylin.systemupgrade.conf b/backend-immutable/tests/data/com.kylin.systemupgrade.conf
+new file mode 100644
+index 0000000..0408835
+--- /dev/null
++++ b/backend-immutable/tests/data/com.kylin.systemupgrade.conf
+@@ -0,0 +1,23 @@
++<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
++
++<!DOCTYPE busconfig PUBLIC
++ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
++ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
++<busconfig>
++    <!-- Only root can own the service -->
++    <policy user="root">
++        <allow own="com.kylin.systemupgrade"/>
++        <allow send_interface="com.kylin.systemupgrade.interface"/>
++    </policy>
++    
++    <!-- Allow anyone to invoke methods on the interfaces -->
++    <policy context="default">
++        <allow send_destination="com.kylin.systemupgrade"
++           send_interface="com.kylin.systemupgrade.interface"/>
++        <allow send_destination="com.kylin.systemupgrade"
++           send_interface="org.freedesktop.DBus.Introspectable"/>
++        <allow send_destination="com.kylin.systemupgrade"
++           send_interface="org.freedesktop.DBus.Properties"/>
++
++    </policy>
++</busconfig>
+diff --git a/backend-immutable/tests/data/com.kylin.systemupgrade.limit b/backend-immutable/tests/data/com.kylin.systemupgrade.limit
+new file mode 100644
+index 0000000..2d80c3a
+--- /dev/null
++++ b/backend-immutable/tests/data/com.kylin.systemupgrade.limit
+@@ -0,0 +1,14 @@
++[whitelist]
++key1 = /usr/bin/kylin-background-upgrade
++key2 = /usr/bin/ukui-control-center
++key3 = /usr/bin/kylin-installer
++key4 = /usr/bin/kylin-uninstaller
++key5 = /usr/bin/kylin-software-properties-service
++key6 = /usr/bin/kylin-source-update
++key7 = /usr/bin/kylin-source-manager
++key8 = /usr/bin/kylin-unattended-upgrade
++key9 = /usr/bin/kylin-software-center
++key10 = /usr/bin/kylin-printer
++key11 = /usr/bin/kylin-printer-applet
++key12 = /usr/bin/hedron-client
++key13 = /usr/bin/kylin-software-center-plugin-synchrodata
+\ No newline at end of file
+diff --git a/backend-immutable/tests/data/inhibit-sleep.conf b/backend-immutable/tests/data/inhibit-sleep.conf
+new file mode 100644
+index 0000000..a4b5275
+--- /dev/null
++++ b/backend-immutable/tests/data/inhibit-sleep.conf
+@@ -0,0 +1,25 @@
++#  This file is part of systemd.
++#
++#  systemd is free software; you can redistribute it and/or modify it
++#  under the terms of the GNU Lesser General Public License as published by
++#  the Free Software Foundation; either version 2.1 of the License, or
++#  (at your option) any later version.
++#
++# Entries in this file show the compile time defaults.
++# You can change settings by editing this file.
++# Defaults can be restored by simply deleting this file.
++#
++# See systemd-sleep.conf(5) for details
++
++[Sleep]
++AllowSuspend=no
++AllowHibernation=no
++#AllowSuspendThenHibernate=yes
++#AllowHybridSleep=yes
++#SuspendMode=
++#SuspendState=mem standby freeze
++#HibernateMode=platform shutdown
++#HibernateState=disk
++#HybridSleepMode=suspend platform shutdown
++#HybridSleepState=disk
++#HibernateDelaySec=180min
+diff --git a/backend-immutable/tests/data/kylin-system-updater b/backend-immutable/tests/data/kylin-system-updater
+new file mode 100644
+index 0000000..3ce1e87
+--- /dev/null
++++ b/backend-immutable/tests/data/kylin-system-updater
+@@ -0,0 +1,10 @@
++/var/log/kylin-system-updater/kylin-system-updater.log.1
++{
++    weekly
++    missingok
++    rotate 3
++    compress
++    notifempty
++    maxsize 10M
++    copytruncate
++}
+diff --git a/backend-immutable/tests/data/kylin-system-updater.db b/backend-immutable/tests/data/kylin-system-updater.db
+new file mode 100644
+index 0000000..934a075
+--- /dev/null
++++ b/backend-immutable/tests/data/kylin-system-updater.db
+@@ -0,0 +1,36 @@
++SQLite format 3���@  ���g���
++��������u�������������������������������������������������g�.?�

��
++t
O�
��
++t	
�
�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������5������������������ ���
����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������g&�%tabledisplaydisplayCREATE TABLE "display"(
++  id INT,
++  check_time TEXT,
++  update_time TEXT,
++  auto_check TEXT,
++  system_version TEXT,
++  auto_backup TEXT,
++  download_limit TEXT,
++  download_limit_value TEXT,
++  allow_unattended_upgrades_shutdown TEXT,
++  update_period TEXT,
++  firstmigration TEXT,
++  autoupdate_allow TEXT,
++  tid TEXT,
++  init_version TEXT)5%I#�indexsqlite_autoindex_updateinfos_1updateinfos�7$##�5tableupdateinfosupdateinfosCREATE TABLE "updateinfos"(
++    id INTEGER   PRIMARY KEY AUTOINCREMENT UNIQUE,
++    appname TEXT NOT NULL,
++    version TEXT Not NULL,
++    description TEXT,
++    date TEXT,
++    status TEXT,
++    keyword TEXT,
++    errorcode TEXT,
++	appname_cn TEXT,
++	status_cn TEXT,
++	changelog TEXT)P++Ytablesqlite_sequencesqlite_sequenceCREATE TABLE sqlite_sequence(name,seq)!�K�����������������������������������������������������������������������3!G!�indexsqlite_autoindex_tid_search_1tid_search�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������} !!�Etabletid_searchtid_searchCREATE TABLE tid_search(
++id INTEGER   PRIMARY KEY AUTOINCREMENT UNIQUE,
++key TEXT,
++tid TEXT
++)
�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������)	�������falsefalsetruefalseNoneyes
��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
++������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������	���
++������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#������*	updateinfos���	displayPinstalled
��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
++����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
+\ No newline at end of file
+diff --git a/backend-immutable/tests/data/kylin-system-updater.service b/backend-immutable/tests/data/kylin-system-updater.service
+new file mode 100644
+index 0000000..df4c1f2
+--- /dev/null
++++ b/backend-immutable/tests/data/kylin-system-updater.service
+@@ -0,0 +1,13 @@
++[Unit]
++Description=kylin-system-updater dbus daemon
++StartLimitIntervalSec=0
++
++[Service]
++Type=dbus
++Restart=always
++RestartSec=3
++BusName=com.kylin.systemupgrade
++ExecStart=/usr/share/kylin-system-updater/kylin-system-updater
++
++[Install]
++WantedBy=multi-user.target
+\ No newline at end of file
+diff --git a/backend-immutable/tests/data/kylin-system-version.conf b/backend-immutable/tests/data/kylin-system-version.conf
+new file mode 100644
+index 0000000..1d12ee6
+--- /dev/null
++++ b/backend-immutable/tests/data/kylin-system-version.conf
+@@ -0,0 +1,3 @@
++[SYSTEM]
++os_version = 
++update_version = 
+\ No newline at end of file
+diff --git a/backend-immutable/tests/data/settings-default.json b/backend-immutable/tests/data/settings-default.json
+new file mode 100644
+index 0000000..28036d1
+--- /dev/null
++++ b/backend-immutable/tests/data/settings-default.json
+@@ -0,0 +1,3 @@
++{
++  "status": "none"
++}
+\ No newline at end of file
+diff --git a/backend-immutable/tests/data/unattended-upgrades-policy.conf b/backend-immutable/tests/data/unattended-upgrades-policy.conf
+new file mode 100644
+index 0000000..a95a67c
+--- /dev/null
++++ b/backend-immutable/tests/data/unattended-upgrades-policy.conf
+@@ -0,0 +1,44 @@
++[autoUpgradePolicy]
++#自动更新的开关
++autoUpgradeState = off
++
++#预下载开关
++preDownload  = off
++
++# 预下载的时间为时间段 例如:10:00-11:00
++preDownloadTime = 09:00-10:00
++
++#添加检查更新的周期 以天为单位
++updateDays = 30
++
++# timing 为定时下载 manaual手动下载
++downloadMode = timing
++
++# 下载的时间为时间段 例如:10:00-11:00
++downloadTime = 20:00-08:00
++
++#安装存在定时timing 手动:manual 关机安装bshutdown
++installMode  = bshutdown
++
++#安装也为时间段 例如:00:00
++installTime = 08:00-20:00
++
++#立即更新随机波动范围(单位:分钟)
++randomRange = 60
++
++#是否开启自动重启 以及自动重启时间可以调节
++automaticReboot = off
++
++#自动重启时间的调节 now为立即重启 重启时间调节 例如00:00
++automaticRebootTime = now
++
++#更新前是否进行备份
++backupbeforeinstall = on
++
++#下发的策略管控  
++[updateStrategiesManager]
++# 策略的开关 False:关 True:开
++strategiesState = False
++
++# 安装策略 default:默认模式 runtime:运行时安装 pre-poweroff:关机安装  
++installType = default
+diff --git a/backend-immutable/tests/data/unattended-upgrades-timestamp b/backend-immutable/tests/data/unattended-upgrades-timestamp
+new file mode 100644
+index 0000000..47eec8e
+--- /dev/null
++++ b/backend-immutable/tests/data/unattended-upgrades-timestamp
+@@ -0,0 +1,4 @@
++[TimeStamp]
++predownload = 2023-7-1 00:00:00
++download = 2023-7-1 00:00:00
++install = 2023-7-1 00:00:00
+diff --git a/backend-immutable/tests/diskManager_unittest.py b/backend-immutable/tests/diskManager_unittest.py
+new file mode 100644
+index 0000000..b4e8b13
+--- /dev/null
++++ b/backend-immutable/tests/diskManager_unittest.py
+@@ -0,0 +1,30 @@
++import unittest
++import sys
++import os
++from SystemUpdater.Core.errors import *
++
++# 添加项目根目录到 sys.path
++from SystemUpdater.Core.diskManager import check_free_space
++class TestCalculator(unittest.TestCase):
++    # def test_diskManagerClassInit(self):
++        # testclass = diskManager()
++        # self.assertIsInstance(testclass, diskManager)
++
++    def test_spaceCheckTrue(self):
++        result = check_free_space(1000,1000)
++        self.assertEqual(True, result)
++
++    def test_spaceCheckFalse(self):
++        with self.assertRaises(UpdateBaseError):
++            result = check_free_space(9999999999999999,100000)
++
++    def test_spaceCheckaddis0(self):
++        result = check_free_space(100000)
++        self.assertEqual(True, result)
++    
++    def test_spaceCheckaddnotis0(self):
++        with self.assertRaises(UpdateBaseError):
++            result = check_free_space(9999999999999999)
++
++if __name__ == "__main__":
++    unittest.main()
+\ No newline at end of file
+diff --git a/backend-immutable/tests/enums.sh b/backend-immutable/tests/enums.sh
+index 3c9c25a..c73eb29 100644
+--- a/backend-immutable/tests/enums.sh
++++ b/backend-immutable/tests/enums.sh
+@@ -22,8 +22,16 @@ CMD_PREFIX=""
+ test_tmpdir="/tmp/ostree-auto-test"
+ 
+ BUILD_MASTER_BRACH="testos/buildmaster/newbranch"
+-
++file_to_monitor="/var/log/kylin-system-updater/kylin-system-updater.log.1"
+ http_port="8889"
+ process_name="python3 -m http.server "$http_port
+ 
+-metadata_string="--add-metadata=ostree.incrementsize='1220202' --add-metadata=update-name_zh_CN='系统更新'  --add-metadata=update-name_en_US='dddddddddd' --add-metadata=description='GalaxyKylinV10SP1SystemUpdate' --add-metadata-string='icon=/usr/share/kylin-update-desktop-config/icon/kylin-update-desktop-system.png' --add-metadata-string=changelog='initialcommit' --add-metadata-string=total_download_size='800MB' --add-metadata-string=total_install_size='1.2GB' --add-metadata-string=update-type='kylin-update-desktop-system'"
++metadata_string="--add-metadata=download-size='8000000000' --add-metadata=install-size='111220202' --add-metadata=update-name_zh_CN='系统更新'  --add-metadata=update-name_en_US='dddddddddd' --add-metadata=description='GalaxyKylinV10SP1SystemUpdate' --add-metadata-string='icon=/usr/share/kylin-update-desktop-config/icon/kylin-update-desktop-system.png' --add-metadata-string=changelog='initialcommit' --add-metadata-string=total_download_size='800MB' --add-metadata-string=total_install_size='1.2GB' --add-metadata-string=update-type='kylin-update-desktop-system'"
++
++TAIL_LINE_NUM="3"
++
++updater_program=$(pwd)/../kylin-system-updater 
++
++PUSH_DIR="/opt/kylin-software-properties"
++PUSH_FILE="$PUSH_DIR/ostree-important.list"
++OS_DATA="/tmp/ostree-auto-test/osdata"
+\ No newline at end of file
+diff --git a/backend-immutable/tests/interface.md b/backend-immutable/tests/interface.md
+new file mode 100644
+index 0000000..addf4bc
+--- /dev/null
++++ b/backend-immutable/tests/interface.md
+@@ -0,0 +1,657 @@
++## DBUS接口
++
++[TOC]
++
++
++
++### 对应版本信息
++
++|        软件包        |            目前版本             | 备注 |
++| :------------------: | :-----------------------------: | :--: |
++| kylin-system-updater | kylin-system-updater 1.4.16kord |      |
++|      aptdaemon       |     1.1.1+bzr982-0kylin32.3     |      |
++|                      |                                 |      |
++
++
++
++### 描述
++
++实现系统升级以python apt库和aptdeamon的形式
++
++
++
++### Dbus接口信息
++
++| 名称           | 含义                              |
++| -------------- | --------------------------------- |
++| BUS类型        | SYSTEM BUS                        |
++| DBUS名称       | com.kylin.systemupgrade           |
++| OBJECT路径     | /com/kylin/systemupgrade          |
++| INTERFACES名称 | com.kylin.systemupgrade.interface |
++| 属性名称       | org.freedesktop.DBus.Properties   |
++
++
++
++### Apt-p2p配置项设置
++
++### Dbus接口信息
++
++| 名称           | 含义                              |
++| -------------- | --------------------------------- |
++| BUS类型        | SYSTEM BUS                        |
++| DBUS名称       | com.kylin.systemupgrade           |
++| OBJECT路径     | /com/kylin/systemupgrade          |
++| INTERFACES名称 | com.kylin.systemupgrade.interface |
++| 属性名称       | org.freedesktop.DBus.Properties   |
++
++
++
++#### Get
++
++- `简介:`获取属性的值
++
++- `入参:` `s`iface:要设置的属性的接口, `s`property:要设置的属性名称
++
++- `出参:` `Variant`变量
++
++- `示例:`
++
++  ```
++  #获取p2p的配置
++  
++  Get(com.kylin.systemupgrade.interface,P2pBootstrap)
++  ```
++
++  
++
++  
++
++#### Set
++
++- `简介:`设置属性的值
++
++- `入参:`  `s`iiface:要设置的属性的接口, `s`iproperty:要设置的属性名称 `Variant`value:要设置的值
++
++- `出参:`
++
++- `示例:`
++
++  ```
++  #设置p2p的配置
++  
++  set("com.kylin.systemupgrade.interface","P2pBootstrap",GLib.Variant('s', "test"))
++  ```
++
++  
++
++
++
++### 方法列表
++
++| Method Name        | Input Args | Output Args | means                             | 异步任务 |
++| ------------------ | ---------- | ----------- | --------------------------------- | ------------------ |
++| UpdateDetect       | 无         | b           | 更新cache,产生组升级列表JSON文件 |  |
++| DistUpgradeAll  | b         | b           | 全部升级                          |  |
++| DistUpgradePartial | b,as         | b           | 部分升级                          |  |
++| DistUpgradeSystem  | b         | b           | 全盘升级                          |  |
++| CancelDownload     | 无         | b           | 取消升级                          |  |
++| InsertInstallState    | ss         | b           | 向display表插入数据                          |  |
++| GtDownloadspeedLimitValue | 无     | b           | 获取当前限速                          |  |
++| SetDownloadspeedMax     | sb         | b          | 设置限速                      |  |
++| GetBackendStatus | 无 | i | 控制获取后端状态 |  |
++| UnattendedUpgradeValue | ss  | bs   | 获取是否允许关机前更新   |  |
++| PurgePackages | as | b | 卸载软件包 |  |
++| InstalldebFile | ssbb | b | 安装本地deb包 |  |
++| DataBackendCollect | ss | b | |  |
++| CheckRebootRequired | s | b | 检查是否需要重启的方法,以及弹窗提示 |  |
++
++
++### Method分析
++
++#### UpdateDetect
++
++- `简介:`更新cache对象,完成从之后拿到系统中所有可升级的包再经过源过滤、白名单等等的过滤,最后输出当前`可升级的包以及分组(JSON配置 输出目录: /var/lib/kylin-system-updater)
++
++- `入参:`无
++- `出参:`True or False 注意:不通过返回值来判断有没有执行成功 通过下面的信号
++- `对应信号:`
++  - `UpdateDetectStatusChanged:` 更新的进度信息和状态信息
++  - `UpdateDetectFinished:`更新的完成的信号
++
++
++
++#### DistUpgradePartial
++
++- `简介:` 升级部分软件包或者分组
++
++- `入参:` `b:` False模式:只进行获取升级列表以及计算修复依赖关系,以及计算是否存在删除的包,`True模式:`直接进行安装的操作 注意:必须选使用False模式获取升级列表以及计算依赖关系再进行True模式 
++
++  `as:` 输入需要升级或者安装的分组 例如 升级系统组:["kylin-update-desktop-system"]
++
++- `出参:`True or False 注意:不通过返回值来判断有没有执行成功 通过下面的信号
++
++- `对应信号:`
++
++  - `UpdateDependResloveStatus:` 升级计算依赖修复反馈信号
++  - `UpdateDloadAndInstStaChanged:`升级安装过程的进度信号以及状态
++  - `UpdateInstallFinished:` 升级安装完成的信号
++
++
++
++#### DistUpgradeAll
++
++- `简介:`升级全部可升级的分组
++
++- `入参:` `b:` False模式:只进行获取升级列表以及计算修复依赖关系,以及计算是否存在删除的包,`True模式:`直接进行安装的操作 注意:必须选使用False模式获取升级列表以及计算依赖关系再进行True模式
++- `出参:`True or False 注意:不通过返回值来判断有没有执行成功 通过下面的信号
++- `对应信号:`
++  - `UpdateDependResloveStatus:` 升级计算依赖修复反馈信号
++  - `UpdateDloadAndInstStaChanged:`升级安装过程的进度信号以及状态
++  - `UpdateInstallFinished:` 升级安装完成的信号
++
++
++
++
++#### UpdateDownloadInfo
++
++- `介绍:`  发送下载包信息信号
++
++- `出参`:   `i:`当前正在下载的项,`i:`所有下载的项,`i:`当前下载的字节,`i:`总的需要下载的字节,`i:`下载速度
++
++- `示例:`
++
++  ```sh
++  current_items = 1, total_items = 1, currenty_bytes = 45 kB, total_bytes = 45 kB, current_cps = 0 kB/s
++  
++  ```
++
++
++
++#### GetBackendStatus
++
++- `介绍:`  获取后端的状态,现在正在处理那些任务
++
++- `入参:` `s:`当前用户的语言变量 例如传入语言环境变量`LANG` 的值`zh_CN.UTF-8` 就会将升级的语言切换为中文 同理其他也能相应设置
++
++- `出参`:   `i:`当前任务ID,整型数字 
++
++- `状态示例列表:`
++
++  ```python
++  ACTION_DEFUALT_STATUS = -1			#默认状态空闲状态
++  ACTION_UPDATE = 0					#处于更新cache状态
++  ACTION_INSTALL = 1					#包括部分升级、全部升级、q
++  ACTION_INSTALL_DEB = 2				#处于安装deb的状态
++  ACTION_CHECK_RESOLVER = 3			#处于计算依赖过程
++  ACTION_DOWNLOADONLY = 4				#单独下载软件包过程
++  ACTION_FIX_BROKEN = 5				#修复依赖的过程
++  ACTION_REMOVE_PACKAGES = 6			#卸载包的状态中
++  ```
++
++
++
++#### UnattendedUpgradeValue
++
++- `介绍:`  设置或获取是否允许关机前更新
++
++- `入参`:   `s:`operation("get"/"set"),`s:`value将要设置的值
++
++- `示例:`
++
++  ```sh
++  operation = "set", value = "false"
++  
++  ```
++
++
++
++#### InstalldebFile
++
++- `简介:`安装本地deb包
++
++- `入参:` `source:(string)` 安装来源,`path:(string)`本地deb包绝对路径,`_check_local_dep:(bool)`出现依赖问题时是否查询本路径下是否存在满足的包,`_auto_satisfy:(bool)`出现依赖问题时是否通过网络下载并安装依赖包
++- `出参:`True or False 
++- `对应信号:`
++   - `InstalldebStatusChanged`:安装过程的进度信号以及状态
++   - `InstalldebFinished`:安装完成的信号
++- `示例:`
++
++  ```sh
++  source = 'kylin-installer', path = '/home/kylin/kylin-video_3.1.0-94.5_amd64.deb', _check_local_dep = 0, _auto_satisfy = 1
++  
++  ```
++
++
++
++#### PurgePackages
++
++- `简介:`卸载系统中的软件包
++
++- `入参:` `as:` 需要卸载的包列表  `s:`当前用户的用户名 例如:kylin用户就传入`kylin`字符串
++
++- `出参:`True or False 出参值不做任何参考意义        `注意:`其中False的时候表示后端正在处理其他任务会报错,其中完成信号也会反馈结果,故不采用方法的返回值来判断错误类型
++
++- `对应信号:`
++
++  - `PurgePkgStatusChanged:`卸载过程的进度信号以及状态
++  - `PurgePackagesFinished:` 卸载完成的信号
++
++- `示例:`
++
++  ```sh
++  _purge_list = ['kylin-video','tree'] cur_user = 'kylin'
++  ```
++
++
++
++#### DataBackendCollect
++
++- `介绍:`  后端数据采集
++
++- `入参`:   `messageType: ` 消息埋点(string), `uploadMessage: ` 上传数据(json格式字符串),必须包含的字段: "packageName"
++
++- `示例:`
++
++  ```sh
++  messageType = "UpdateInfos", uploadMessage = "{\"packageName\":\"kylin-system-updater\",\"source\":\"kylin-system-updater\",\"status\":\"True\",\"errorCode\":\"\",\"versionOld\":\"1.2.13.2kord\",\"versionNew\":\"1.2.17.1kord\"}"
++  
++  messageType: 消息埋点(string) "UpdateInfos"、"InstallInfos"、"RemoveInfos"...
++  source: 安装来源 "kylin-installer"、"unattented-upgrade"、"kylin-software-center"、"kylin-system-updater"...
++  status: 安装或卸载状态 "True"/"False"
++  errorCode: 错误信息 ""/"..."
++  versionOld: 旧版本号 "1.2.13.2kord"
++  versionNew: 新版本号 "1.2.17.1kord"
++  
++  ```
++
++
++
++#### CheckRebootRequired
++
++- `介绍:`  检查是否需要重启的方法,以及弹窗提示  
++- `入参`:   `s:`标识那个应用调的此接口(如自动更新可填入字符串“autoyupgrade”)
++- `出参:`True or False 执行的结果
++
++
++
++#### SetConfigValue
++
++- `简介:`设置配置文件的值 配置文件的目录`/var/lib/kylin-system-updater/system-updater.conf`
++
++- `入参:` `section`, `option`,` value` 不管布尔、列表的数据类型都转化成字符串类型来写入 
++
++- 例如传入"InstallModel","shutdown_install","False"
++
++  ```
++  [InstallMode]
++  shutdown_install = True
++  manual_install = False
++  auto_install = False
++  pkgs_install = 
++  pkgs_upgrade = 
++  pkgs_remove = 
++  ```
++
++- `出参:`True :设置值成功 False: 设置失败
++
++#### GetConfigValue
++
++- `简介:`获取配置文件的值 配置文件的目录`/var/lib/kylin-system-updater/system-updater.conf`
++
++- `入参:` `section`,` option`  例如传入"InstallModel","shutdown_install" 
++
++- `出参:` `bool:`True :获取值成功 False: 获取失败 `Value:`值都以字符串类型来返回 
++
++  ```
++  [InstallMode]
++  shutdown_install = True
++  manual_install = False
++  auto_install = False
++  pkgs_install = 
++  pkgs_upgrade = 
++  pkgs_remove = 
++  ```
++
++
++
++#### CheckInstallRequired
++
++- `简介:`检查当前系统是否需要关机安装或者重启安装
++- `入参:` 无
++- `出参:` `int:`  类型返回值 表示当前系统是否需要安装 返回值数值含义如下。简要为0时不需要安装,不为零时需要进行提示安装
++  - `1`  手动更新请求当前系统在关机时进行安装软件包
++  -  `2`  自动更新请求当前系统在关机时进行安装软件包
++  - `0` 当前系统不需要进行安装  
++
++
++
++#### FixBrokenDepends
++
++- `简介:` 修复当前的系统Apt环境,收到`UpdateFixBrokenStatus`后进行调用,类似于调用apt install -f 来进行修复
++- `入参:` 无
++- `出参:` True or False 执行的结果 无实际意义
++- `对应信号:`
++  - `FixBrokenStatusChanged:` 修复依赖的状态信号 可不使用
++
++
++
++#### MountSquashfsSource
++
++- `简介:` 挂载离线源squashfs
++- `入参:` `s:` 挂载文件的位置
++- `出参:` `b:` True or False 执行的结果,`s:` 字符类型错误信息描述
++
++
++
++### Signal列表
++
++| Signal Name            | Output Args | means                    |
++| ---------------------------- | ----------- | ------------------------ |
++| UpdateDetectStatusChanged    | i,s          | 更新进度信息以及状态信息 |
++| UpdateDetectFinished         | b,as,s,s       | 更新完成信号             |
++| UpdateDloadAndInstStaChanged | as,i,s,s | 升级的进度信号以及状态   |
++| UpdateInstallFinished       | b,as,s,s       | 升级完成的信号           |
++| UpdateDownloadInfo           | i,i,u,u,i | 发送下载包信息信号       |
++| UpdateDependResloveStatus           | b,b,s       | 更新依赖修复信息       |
++| DistupgradeDependResloveStatus           | b,s       | 更新全盘修复信息       |
++| Cancelable                   | b           | 是否可取消               |
++| UpdateSqlitSingle |  |  |
++| FixBrokenStatusChanged | iiisss | 修复依赖的状态信号 |
++| PurgePackagesFinished | iss | 卸载完成信号 |
++| PurgePkgStatusChanged | bss | 卸载进度信息以及状态信息 |
++| RebootLogoutRequired | s | 请求重启或者注销的信号 |
++| UpdateInstallFinished | b,as,s,s | 下载完成的信号           |
++
++
++
++### Signal分析
++
++#### UpdateDetectStatusChanged
++
++- `介绍:`更新的进度信息和状态信息
++
++- `出参`:`i:`更新的进度信息从0-100%,`s:`更新的状态信息,
++
++- `示例:`
++
++  ```sh
++  progress = 9 , status = 正在解决依赖关系
++  progress = 92 , status = 正在载入软件列表
++  progress = 92 , status = 完成
++  ```
++
++  
++
++#### UpdateDetectFinished
++
++- `介绍:`更新的完成的信号
++
++- `出参`:   `b:`更新是否成功,`as:`可升级的组列表,`s:`产生错误的结果,`s:`产生错误的原因
++
++- `示例:`
++
++  ```sh
++  success = True , upgrade_group = ['kylin-update-desktop-system', 'tree', 'texinfo', 'kylin-update-manager', 'dnsmasq-base', 'vino', 'dpkg-dev', 'ghostscript', 'atril', 'wpasupplicant', 'eom', 'eom-common', 'fcitx-bin', 'fcitx-data', 'fcitx-frontend-gtk2', 'wps-office'], error_string =  , error_desc = 
++  
++  error_string = 获取更新软件推送失败,请稍后再进行尝试更新 , error_desc = 推送服务器连接异常 
++  
++  ```
++
++#### UpdateDependResloveStatus
++
++- `介绍:`升级计算依赖修复反馈信号
++
++- `出参`:   `b:`修复依赖关系是否成功,`b:`是否存在升级需要卸载的包,`as:`卸载的包列表,`as:`卸载的包的描述信息,`as:`卸载此包的原因 升级安装那些包导致的,`s:`产生错误的结果,`s:`产生错误的原因
++
++- `示例:`
++
++  ```sh
++  UpdateDependResloveStatus:resolver_status = True , remove_status = True , remove_pkgs = ['kylin-burner-i18n'],pkg_raw_description = ['Sophisticated CD/DVD burning application - localizations files'] ,delete_desc = ['kylin-burner-i18n 将要被删除,由于升级 kylin-burner'],error_string =  , error_desc =  
++  
++  ```
++
++
++
++
++#### UpdateFixBrokenStatus
++
++- `介绍:`更新检查过程中是否需要修复系统Apt的环境,提示是否存在卸载软件包的情况
++
++- `出参`:   `b:`是否能修复系统环境,`b:`是否存在修复需要卸载的包,`as:`卸载的包列表,`as:`卸载的包的描述信息,`as:`卸载此包的原因,`s:`产生错误的结果,`s:`产生错误的原因
++
++- `示例:`
++
++  ```sh
++  UpdateDependResloveStatus:resolver_status = True , remove_status = True , remove_pkgs = ['kylin-burner-i18n'],pkg_raw_description = ['Sophisticated CD/DVD burning application - localizations files'] ,delete_desc = ['kylin-burner-i18n 将要被删除,由于升级 kylin-burner'],error_string =  , error_desc =  
++  
++  ```
++
++
++
++
++#### UpdateDloadAndInstStaChanged
++
++- `介绍:`  升级安装过程的进度信号以及状态
++
++- `出参`:     `as:`当前那些组在升级安装   `i:`更新的进度信息从0-100%,`s:`更新的状态信息  `s:`下载的细节信息
++
++- ` 示例:`
++
++  ```sh
++  groups_list = ['kylin-update-desktop-system'] progress = 15 , status = 下载中 current_details = 下载中 tree
++  ```
++
++  
++
++#### UpdateInstallFinished
++
++- `介绍:`  升级安装完成的信号
++
++- `出参`:   `b:`升级是否成功,`as:`可升级的组列表,`s:`产生错误的结果,`s:`产生错误的原因
++
++- `示例:`
++
++  ```sh
++  pdateInstallFinished success = True , upgrade_group = ['tree'], error_string = 系统升级完成。 , error_desc =
++  
++  ```
++
++
++
++#### UpdateDownloadFinished
++
++- `介绍:`  下载完成的信号
++
++- `出参`:   `b:`下载是否成功,`as:`可升级的组列表,`s:`产生错误的结果,`s:`产生错误的原因
++
++- `示例:`
++
++  ```sh
++  pdateInstallFinished success = True , upgrade_group = ['tree'], error_string = 系统升级完成。 , error_desc =
++  
++  ```
++
++
++
++#### FixBrokenStatusChanged
++
++- `介绍:`  修复依赖过程中的状态反馈信号
++
++- `出参`:     `i:`修复依赖是否完成   `i:`修复依赖过程是否成功`注意:只有修复完成时,修复依赖是否成功才有意义`,`i:`修复的进度信息  `s:`修复的状态信息 `s:`产生错误的结果,`s:`产生错误的原因
++
++- ` 示例:`
++
++  ```sh
++  emit FixBrokenStatusChanged finished = False , success = True,progress = 66 , status = 正在应用更改,error_string =  , error_desc = 
++  ```
++
++- 
++
++
++
++#### PurgePkgStatusChanged
++
++- `介绍:`卸载的进度信息和状态信息以及状态的细节信息
++
++- `出参`:`i:`卸载的进度信息从0-100%,`s:`卸载的状态信息,`s:`卸载的细节信息
++
++- `示例:`
++
++  ```sh
++  INFO:emit PurgePkgStatusChanged progress = 63 , status = 正在应用更改 ,current_details = 正在准备删除 kylin-video
++  INFO:emit PurgePkgStatusChanged progress = 76 , status = 正在应用更改 ,current_details = 正在卸载 kylin-video
++  
++  ```
++
++
++
++
++#### PurgePackagesFinished
++
++- `介绍:`卸载的完成的信号
++
++- `出参`:   `b:`卸载是否成功,`s:`产生错误的结果,`s:`产生错误的原因
++
++- `示例:`
++
++  ```sh
++  #卸载完成
++  PurgePackagesFinished success = True , error_string = 卸载完成。 , error_desc = 
++  
++  #卸载失败
++  PurgePackagesFinished success = False , error_string = 软件包不存在 , error_desc = 检查包名的拼写是否正确,以及是否启用了相应的仓库。
++  PurgePackagesFinished success = False , error_string = 软件包没有安装 , error_desc = 不需要进行卸载。
++  
++  #卸载失败 由于正在处理其他任务也同样会报错
++  PurgePackagesFinished success = False , error_string = 其他任务正在更新升级中,请稍后再卸载。 , error_desc = 
++  ```
++
++  
++
++#### InstalldebStatusChanged
++
++- `介绍:`安装的进度信息和状态信息以及状态的细节信息
++
++- `出参`:`i:`安装的进度信息从0-100%,`s:`安装的状态信息,`s:`安装的细节信息
++
++- `示例:`
++
++  ```sh
++  InstalldebStatusChanged progress = 57 , status = 正在应用更改 ,current_details = 正在配置 python3-bandit
++  InstalldebStatusChanged progress = 57 , status = 正在应用更改 ,current_details = python3-bandit 已安装
++  
++  ```
++
++
++
++
++#### InstalldebFinished
++
++- `介绍:`安装的完成的信号
++
++- `出参`:   `b:`安装是否成功,`s:`产生错误的结果,`s:`产生错误的原因
++
++- `示例:`
++
++  ```sh
++  #安装完成
++  InstalldebFinished success = True , error_string =  , error_desc =
++  
++  #安装失败 缺少依赖的
++  InstalldebFinished success = False , error_string = bandit dependency is not satisfied  , error_desc = python3-bandit
++  
++  #安装失败 选择从网络拉依赖 网络断开 报网络错误
++  InstalldebFinished success = False , error_string = 下载软件包文件失败 , error_desc = 检查您的网络连接。
++  ```
++
++
++
++
++#### RebootLogoutRequired
++
++- `介绍:`请求重启和注销的信号
++
++- `出参`:   `s:` "reboot" 表示重启 "logout"表示注销
++
++- `示例:`
++
++  ```sh
++  Emitting RebootLogoutRequired required_status = reboot
++  ```
++
++
++
++#### InstallDetectStatus
++
++- `介绍:`下载安装前的状态检查
++
++- `出参`:   `b:`检查出错时为`False`,没有错误`success`,`s:`产生错误的码
++
++- 错误码示例:
++
++  ```python
++  ERROR_NOT_DISK_SPACE = "error-not-disk-space"
++  ```
++
++- `示例:`
++
++  ```sh
++  #表示出现磁盘已满的错误z
++  InstallDetectStatus success = False , error_code = "error-not-disk-space"
++  ```
++
++
++
++
++
++
++
++
++后端日志:`/var/log/kylin-system-updater/kylin-system-updater.log.1`
++
++### 更新过程报错信息总结
++
++| 错误信息             | 错误原因                                                     | 解决办法                                 |
++| -------------------- | ------------------------------------------------------------ | ---------------------------------------- |
++| 下载软件仓库信息失败 | 源存在问题,使用apt update检查,若存在报错则更新管理器无问题 | 检查源是否可以使用                       |
++| 无法访问源管理服务器 | 源管理服务器存在问题                                         | 源管理服务器是否可用或者检查源服务器配置 |
++| 软件索引已经损坏     | 当前系统中cache被破坏,apt无法使用                           | 终端检查错误原因进行解决                 |
++| 无法初始化软件包信息 | apt存在某些问题                                              | 具体错误原因查看日志相应解决             |
++| 无法获取组配置软件包 | 源中不存在kylin-update-desktop-config                        | 将此包放入源仓库或者写配置文件不强制安装 |
++| 无法读取推送升级列表 | 读取推送列表出现问题                                         | 检查important.list是否存在               |
++| 获取软件推送失败     | 老版本文案同 无法访问源管理服务器解决                        |                                          |
++
++
++
++### 安装过程报错信息总结
++
++| 错误信息           | 错误原因                       | 解决办法                           |
++| ------------------ | ------------------------------ | ---------------------------------- |
++| 软件包操作失败     | 被升级的软件包有问题           | 检查后端log日志查看那个包存在问题  |
++| 下载软件包文件失败 | 网络原因的或者这个软件包的仓库 | 检查网络以及源仓库                 |
++| 磁盘空间不足       | 磁盘的空间不足                 | 查看日志那些目录空间不足           |
++| 不能计算升级       | 无法计算依赖关系               | 检查日志那个包出现的问题,相应解决 |
++|                    |                                |                                    |
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+diff --git a/backend-immutable/tests/kylin-system-updater b/backend-immutable/tests/kylin-system-updater
+new file mode 100755
+index 0000000..baf60ca
+--- /dev/null
++++ b/backend-immutable/tests/kylin-system-updater
+@@ -0,0 +1,80 @@
++#!/usr/bin/python3
++
++from SystemUpdater.UpdateManager import UpdateManager
++from gettext import gettext as _
++import logging
++from optparse import OptionParser
++import dbus
++dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
++import signal
++import os
++import sys
++import gettext
++from SystemUpdater.configs import settings
++from SystemUpdater.Core.LogManager import get_logfile as logfile
++from SystemUpdater.constants import DEFAULT_OS_NAME
++gettext.bindtextdomain('kylin-system-updater', '/usr/share/locale')
++gettext.textdomain('kylin-system-updater')
++_ = gettext.gettext
++
++#定义日志的格式 
++FORMAT = "%(asctime)s [%(levelname)s]: %(message)s"
++FORMAT_DEBUG = '%(asctime)-15s %(levelname)s(%(filename)s:%(lineno)d):%(message)s'
++
++def signal_handler_term(signal, frame):
++    # type: (int, object) -> None
++    logging.warning("SIGTERM received, will stop")
++    app.dbus_send.Quit(None)
++
++if __name__ == "__main__":
++  # Begin parsing of options
++  parser = OptionParser()
++  parser.add_option ("-d", "--debug", action="store_true", default=False,
++                    help=_("Show debug messages"))
++  parser.add_option("-r", "--replace",
++                    default=False,
++                    action="store_true", dest="replace",
++                    help=_("Quit and replace an already running "
++                            "daemon"))
++  parser.add_option("", "--sysroot", default=None,
++                      action="store", type="string", dest="sysroot",
++                      help=_("Import sysroot path in the given path"))
++  parser.add_option("", "--os", default=DEFAULT_OS_NAME,
++                      action="store", type="string", dest="os",
++                      help=_("Import os name in the given string"))
++  parser.add_option("-p", "--prohibit-shutdown",
++                    default=False,
++                    action="store_true", dest="prohibit_shutdown",
++                    help=_("close auto shutdown"))
++  parser.add_option ("-n","--no-update-source", action="store_false",
++                    dest="update_source", default=True,
++                    help=_("Do not check for updates source when updating"))
++  parser.add_option("--no-check-network",
++                    default=True,
++                    action="store_false", dest="check_network",
++                    help=_("Quit and close check network"))
++
++  (options, args) = parser.parse_args()
++
++  # 将命令行参数 加载到settings的配置项中
++  settings.update(vars(options))
++
++  if os.getuid() != 0:
++      print(_("You need to be root to run this application"))
++      sys.exit(1)
++
++  # ensure that we are not killed when the terminal goes away e.g. on
++  # shutdown
++  signal.signal(signal.SIGHUP, signal.SIG_IGN)
++  signal.signal(signal.SIGINT,signal_handler_term)
++
++  if options.debug:
++    logging.basicConfig(format=FORMAT,level=logging.INFO,datefmt='%m-%d,%H:%M:%S')
++  else:
++    logging.basicConfig(format=FORMAT,level=logging.INFO,datefmt='%m-%d,%H:%M:%S',filename = logfile(),filemode = 'a')
++
++  logging.info('kylin-system-updater starting ...')
++
++  app = UpdateManager(options)
++
++  app.run()
+\ No newline at end of file
+diff --git a/backend-immutable/tests/kylin-upgrade-strategies b/backend-immutable/tests/kylin-upgrade-strategies
+new file mode 100755
+index 0000000..c60e461
+--- /dev/null
++++ b/backend-immutable/tests/kylin-upgrade-strategies
+@@ -0,0 +1,81 @@
++#!/usr/bin/python3
++
++from SystemUpdater.UpgradeStrategies import UpgradeStrategies
++from gettext import gettext as _
++import logging
++from optparse import OptionParser
++import dbus
++dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
++import signal
++import os
++import sys
++import gettext
++
++from SystemUpdater.Core.LogManager import upgrade_strategies_logfile as logfile
++
++gettext.bindtextdomain('kylin-system-updater', '/usr/share/locale')
++gettext.textdomain('kylin-system-updater')
++_ = gettext.gettext
++
++#定义日志的格式 
++FORMAT = "%(asctime)s [%(levelname)s]: %(message)s"
++
++FORMAT_DEBUG = '%(asctime)-15s %(levelname)s(%(filename)s:%(lineno)d):%(message)s'
++
++def signal_handler_term(signal, frame):
++    # type: (int, object) -> None
++    logging.warning("SIGTERM received, will stop")
++    app.dbus_send.Quit(None)
++
++if __name__ == "__main__":
++  # Begin parsing of options
++  parser = OptionParser()
++  parser.add_option ("-d", "--debug", action="store_true", default=False,
++                    help=_("Show debug messages"))
++  parser.add_option("-r", "--replace",
++                    default=False,
++                    action="store_true", dest="replace",
++                    help=_("Quit and replace an already running "
++                            "daemon"))
++
++
++  (options, args) = parser.parse_args()
++
++  if os.getuid() != 0:
++      print(_("You need to be root to run this application"))
++      sys.exit(1)
++      
++  # set debconf to NON_INTERACTIVE
++  os.environ["DEBIAN_FRONTEND"] = "noninteractive"
++  os.environ["TERM"] = "xterm"
++  os.environ["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
++
++  #当不存在语言变量时 默认显示中文
++  if not "LANGUAGE" in os.environ:
++    os.environ["LANGUAGE"] = "zh_CN.UTF-8"
++  
++  #当不存在语言变量时 默认显示中文
++  if not "LANG" in os.environ:
++    os.environ["LANG"] = "zh_CN.UTF-8"
++
++  #做一些规范处理
++  if os.environ["LANGUAGE"] == "en":
++    os.environ["LANGUAGE"] = "en_US.UTF-8"
++  if os.environ["LANGUAGE"] == "zh_CN:en" or os.environ["LANGUAGE"] == "zh_CN:zh":
++    os.environ["LANGUAGE"] = "zh_CN.UTF-8"
++
++  # ensure that we are not killed when the terminal goes away e.g. on
++  # shutdown
++  signal.signal(signal.SIGHUP, signal.SIG_IGN)
++  signal.signal(signal.SIGINT,signal_handler_term)
++
++  if options.debug:
++    logging.basicConfig(format=FORMAT,level=logging.INFO,datefmt='%m-%d,%H:%M:%S')
++  else:
++    logging.basicConfig(format=FORMAT,level=logging.DEBUG,datefmt='%m-%d,%H:%M:%S',filename = logfile(),filemode = 'a')
++
++
++  logging.info('Updater Config Manager Daemon(LANGUAGE:%s LANG:%s) starting ...',os.environ["LANGUAGE"],os.environ["LANG"])
++
++  app = UpgradeStrategies(options)
++  app.run()
+\ No newline at end of file
+diff --git a/backend-immutable/tests/libtest-core.sh b/backend-immutable/tests/libtest-core.sh
+index 945d285..0d8f9bf 100644
+--- a/backend-immutable/tests/libtest-core.sh
++++ b/backend-immutable/tests/libtest-core.sh
+@@ -1,30 +1,3 @@
+-# Core source library for shell script tests; the
+-# canonical version lives in:
+-#
+-#   https://github.com/ostreedev/ostree
+-#
+-# Known copies are in the following repos:
+-#
+-# - https://github.com/projectatomic/rpm-ostree
+-#
+-# Copyright (C) 2017 Colin Walters <walters@verbum.org>
+-#
+-# SPDX-License-Identifier: LGPL-2.0+
+-#
+-# This library is free software; you can redistribute it and/or
+-# modify it under the terms of the GNU Lesser General Public
+-# License as published by the Free Software Foundation; either
+-# version 2 of the License, or (at your option) any later version.
+-#
+-# This library is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-# Lesser General Public License for more details.
+-#
+-# You should have received a copy of the GNU Lesser General Public
+-# License along with this library; if not, write to the
+-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-# Boston, MA 02111-1307, USA.
+ 
+ fatal() {
+     echo $@ 1>&2; exit 1
+@@ -34,12 +7,6 @@ assert_not_reached () {
+     fatal "$@"
+ }
+ 
+-# Some tests look for specific English strings. Use a UTF-8 version
+-# of the C (POSIX) locale if we have one, or fall back to en_US.UTF-8
+-# (https://sourceware.org/glibc/wiki/Proposals/C.UTF-8)
+-#
+-# If we can't find the locale command assume we have support for C.UTF-8
+-# (e.g. musl based systems)
+ if type -p locale >/dev/null; then
+     export LC_ALL=$(locale -a | grep -iEe '^(C|en_US)\.(UTF-8|utf8)$' | head -n1 || true)
+     if [ -z "${LC_ALL}" ]; then fatal "Can't find suitable UTF-8 locale"; fi
+diff --git a/backend-immutable/tests/libtest.sh b/backend-immutable/tests/libtest.sh
+index c04cbe9..d4b7459 100644
+--- a/backend-immutable/tests/libtest.sh
++++ b/backend-immutable/tests/libtest.sh
+@@ -1,16 +1,128 @@
+ . ./enums.sh
+ . ./libtest-core.sh
+ 
+-if [ ! -d "$test_tmpdir" ]; then
+-    mkdir -p "$test_tmpdir"
+-    echo "创建测试目录: $test_tmpdir"
+-else
+-    echo "创建测试目录: $test_tmpdir"
+-    sudo chattr -R -i $test_tmpdir/* >/dev/null 2>&1 || true
+-    chmod -R 777 $test_tmpdir/* >/dev/null 2>&1 || true
+-    rm -rf $test_tmpdir
+-    mkdir -p "$test_tmpdir"
+-fi
++TRUE=true
++FALSE=false
++
++DEBUG="$FALSE"
++
++for arg in "$@"; do
++    if [ "$arg" == "-d" ]; then
++        DEBUG="$TRUE"
++        # 如果需要执行某些操作,可以放在这里
++    fi
++done
++
++BOLD="$(tput bold 2>/dev/null || printf '')"
++GREY="$(tput setaf 0 2>/dev/null || printf '')"
++UNDERLINE="$(tput smul 2>/dev/null || printf '')"
++RED="$(tput setaf 1 2>/dev/null || printf '')"
++GREEN="$(tput setaf 2 2>/dev/null || printf '')"
++YELLOW="$(tput setaf 3 2>/dev/null || printf '')"
++BLUE="$(tput setaf 4 2>/dev/null || printf '')"
++MAGENTA="$(tput setaf 5 2>/dev/null || printf '')"
++NO_COLOR="$(tput sgr0 2>/dev/null || printf '')"
++
++info() {
++    printf '\n%s\n\n' "${BOLD}${YELLOW}! $*${NO_COLOR}"
++}
++
++warn() {
++    printf '%s\n' "${YELLOW}! $*${NO_COLOR}"
++}
++
++error() {
++    printf '%s\n\n' "${BOLD}${RED}>${NO_COLOR} ${BOLD}${RED}$*${NO_COLOR}" 
++}
++
++fn_simulate_ostree_system() {
++    # 模拟ostree系统的环境 进行测试
++    # 主要做的:
++    # - 初始化一个ostree仓库:testos-repo
++    # - 在osdata目录创建模拟一些系统文件 and 提交两次到testos-repo 仓库
++    # - 复制osdata数据到osdata-devel,做出修改然后再次提交
++    # - 用init-fs创建sysroot 和 os-init 和 syslinux
++    # - 提交一个新的commit用空目录,标记初始分支($BUILD_MASTER_BRACH)为EOL 重新定向到新分支(testos/buildmaster/newbranch)
++
++    # 删除所有历史测试数据 重新创建测试
++    if [ ! -d "$test_tmpdir" ]; then
++        mkdir -p "$test_tmpdir"
++        echo "创建测试目录: $test_tmpdir"
++    else
++        echo "创建测试目录: $test_tmpdir"
++        sudo chattr -R -i $test_tmpdir/* >/dev/null 2>&1 || true
++        chmod -R 777 $test_tmpdir/* >/dev/null 2>&1 || true
++        rm -rf $test_tmpdir
++        mkdir -p "$test_tmpdir"
++    fi
++
++    if [ ! -d "$PUSH_DIR" ]; then
++        mkdir -p "$PUSH_DIR"
++    fi
++
++    # 创建ostree仓库 仓库类型 and boot类型 包括默认开启一个远程
++    setup_os_repository "archive" "syslinux"
++
++    cd ${test_tmpdir}
++    ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo remote add --set=gpg-verify=false testos $(cat httpd-address)/ostree/testos-repo
++
++    ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull testos $BUILD_MASTER_BRACH > /dev/null
++    rev=$(${CMD_PREFIX} ostree --repo=sysroot/ostree/repo rev-parse $BUILD_MASTER_BRACH)
++    echo "拉取分支:$BUILD_MASTER_BRACH 从远程仓库testos-repo and revision=${rev}"
++
++    echo "部署分支:$BUILD_MASTER_BRACH"
++    ${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os=testos testos:$BUILD_MASTER_BRACH > /dev/null
++    assert_has_dir sysroot/boot/ostree/testos-${bootcsum}
++}
++
++moniter_signal_success () {
++    signal=$1
++    
++    tail -F -n $TAIL_LINE_NUM "$file_to_monitor" | while read -r line; do
++        if echo -e "$line" | grep -q $signal" success = True"; then
++            echo -e "$line \n"
++            break
++        fi
++
++        if echo "$line" | grep -q 'ERROR'; then
++            echo -e "\033[91m$line\033[0m"
++        else
++            echo "$line"
++        fi
++    done
++}
++
++moniter_signal_failed () {
++    signal=$1
++    
++    tail -F -n $TAIL_LINE_NUM "$file_to_monitor" | while read -r line; do
++        if echo -e "$line" | grep -q $signal" success = False"; then
++            echo -e "$line \n"
++            break
++        fi
++
++        if echo "$line" | grep -q 'ERROR'; then
++            echo -e "\033[91m$line\033[0m"
++        else
++            echo "$line"
++        fi
++    done
++}
++
++moniter_string () {
++    tail -F -n $TAIL_LINE_NUM "$file_to_monitor" | while read -r line; do
++        if echo -e "$line" | grep "$1"; then
++            echo -e "$line \n"
++            break
++        fi
++
++        if echo "$line" | grep -q 'ERROR'; then
++            echo -e "\033[91m$line\033[0m"
++        else
++            echo "$line"
++        fi
++    done
++}
+ 
+ os_repository_new_commit ()
+ {
+@@ -50,8 +162,6 @@ os_repository_new_commit ()
+     mkdir -p usr/etc/new-default-dir
+     echo "a new default dir and file" > usr/etc/new-default-dir/moo
+     
+-    # dd if=/dev/zero of=usr/etc/new-default-dir/bigfile  bs=1M count=1000
+-
+     echo "content iteration ${content_iteration}" > usr/bin/content-iteration
+ 
+     echo -n "创建新分支:$branch and commit revision:"
+@@ -198,7 +308,7 @@ EOF
+ 
+     $process_name >/dev/null 2>&1 &
+     child_pid=$!
+-    trap "kill -9 $child_pid" EXIT
++    trap "kill -9 $child_pid >/dev/null 2>&1 | true" EXIT
+     # 延迟一段时间 等待服务开启 
+     sleep 2
+ 
+@@ -206,4 +316,10 @@ EOF
+     port=$(cat ${test_tmpdir}/httpd-port)
+     echo "http://localhost:${port}" > ${test_tmpdir}/httpd-address
+     cd ${oldpwd} 
+-}
+\ No newline at end of file
++}
++
++if ! [ "$DEBUG" = "$TRUE" ]; then
++    info "正在启动系统更新的后台服务...  参数:$@"
++    $updater_program -r --sysroot=$test_tmpdir/sysroot -p --os=testos "$@" &
++    sleep 3
++fi
+\ No newline at end of file
+diff --git a/backend-immutable/tests/po/ChangeLog b/backend-immutable/tests/po/ChangeLog
+new file mode 100644
+index 0000000..123b7dd
+--- /dev/null
++++ b/backend-immutable/tests/po/ChangeLog
+@@ -0,0 +1,6 @@
++2021-09-16  XueYi Luo <luoxueyi@kylinos.cn>
++
++	* zh_CN.po: Updated Simplified Chinese translation.
++	* zh_HK.po: Updated translation for HongKong,china.
++	* zh_TW.po: Updated translation for Taiwan,China.
++
+diff --git a/backend-immutable/tests/po/Makefile b/backend-immutable/tests/po/Makefile
+new file mode 100644
+index 0000000..dacf43d
+--- /dev/null
++++ b/backend-immutable/tests/po/Makefile
+@@ -0,0 +1,28 @@
++
++top_srcdir=`pwd`/..
++
++DOMAIN=kylin-system-updater
++PO_FILES := $(wildcard *.po)
++CONTACT=sebastian.heinlein@web.de
++XGETTEXT_ARGS = --msgid-bugs-address=$(CONTACT)
++XGETTEXT_ARGS += --keyword=unicode_gettext:2 --keyword=unicode_ngettext:2,3
++XGETTEXT_ARGS += --language=python
++
++all: update-po
++
++# update the pot
++$(DOMAIN).pot:
++	XGETTEXT_ARGS="$(XGETTEXT_ARGS)" intltool-update -p -g $(DOMAIN)
++
++# merge the new stuff into the po files
++merge-po: $(PO_FILES)
++	XGETTEXT_ARGS="$(XGETTEXT_ARGS)" intltool-update -r -g $(DOMAIN); 
++
++# create mo from the pos
++%.mo : %.po
++	mkdir -p mo/$(subst .po,,$<)/LC_MESSAGES/ 
++	msgfmt $< -o mo/$(subst .po,,$<)/LC_MESSAGES/$(DOMAIN).mo 
++
++# dummy target 
++update-po: $(DOMAIN).pot merge-po $(patsubst %.po,%.mo,$(wildcard *.po))
++
+diff --git a/backend-immutable/tests/po/POTFILES.in b/backend-immutable/tests/po/POTFILES.in
+new file mode 100644
+index 0000000..5b8c84f
+--- /dev/null
++++ b/backend-immutable/tests/po/POTFILES.in
+@@ -0,0 +1,9 @@
++[encoding: UTF-8]
++SystemUpdater/backend/BackendOstreeNext.py
++SystemUpdater/backend/__init__.py
++SystemUpdater/UpdateManager.py
++SystemUpdater/Core/MyCache.py
++SystemUpdater/Core/UpdateList.py
++SystemUpdater/Core/Database.py
++SystemUpdater/UpdateManagerDbus.py
++SystemUpdater/Core/enums.py
+diff --git a/backend-immutable/tests/po/POTFILES.skip b/backend-immutable/tests/po/POTFILES.skip
+new file mode 100644
+index 0000000..e69de29
+diff --git a/backend-immutable/tests/po/bo_CN.po b/backend-immutable/tests/po/bo_CN.po
+new file mode 100644
+index 0000000..be65457
+--- /dev/null
++++ b/backend-immutable/tests/po/bo_CN.po
+@@ -0,0 +1,242 @@
++# SOME DESCRIPTIVE TITLE.
++# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
++# This file is distributed under the same license as the PACKAGE package.
++# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
++#
++#, fuzzy
++msgid ""
++msgstr ""
++"Project-Id-Version: PACKAGE VERSION\n"
++"Report-Msgid-Bugs-To: kylinos.cn\n"
++"POT-Creation-Date: 2012-06-14 00:53+0100\n"
++"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
++"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
++"Language-Team: LANGUAGE <LL@li.org>\n"
++"Language: \n"
++"MIME-Version: 1.0\n"
++"Content-Type: text/plain; charset=UTF-8\n"
++"Content-Transfer-Encoding: 8bit\n"
++
++msgid "Unable to access the source management server, please try again later"
++msgstr "འདྲི་རྩད་ཀྱི་འབྱུང་ཁུངས་དོ་དམ་ཞབས་ཞུའི་ཡོ་བྱད་ལ་འཚམས་འདྲི་བྱེད་ཐབས་མེད་པས་རྗེས་སུ་ཡང་བསྐྱར"
++
++msgid "Access to the source management server timed out, please try again later"
++msgstr "འཚམས་འདྲིའི་འབྱུང་ཁུངས་ཀྱི་དོ་དམ་ཞབས་ཞུའི་ཡོ་བྱད་དུས་ལས་བརྒལ་བས་རྗེས་སུ་ཡང་བསྐྱར་ཚོད་ལྟ་བྱེད་རོགས"
++
++msgid "Check if your network requires authentication?"
++msgstr "ཁྱེད་ཀྱི་དྲ་རྒྱར་ཞིབ་བཤེར་བྱེད་དགོས་སམ།"
++
++msgid "Check your source public key signature"
++msgstr "ཁྱེད་ཀྱི་འབྱུང་ཁུངས་ལ་ཞིབ་བཤེར་བྱས་ནས་མིང་རྟགས་བཀོད།"
++
++msgid "update important list occur Exception"
++msgstr "ལག་ཏུ་བླངས་ནས་རྒྱུན་ལྡན་མིན་པ་བྱུང་ན་རྗེས་སུ་ཡང་བསྐྱར་ཚོད་ལྟ་ཞིག་གནང་རོགས།"
++
++msgid "You need to be root to run this application"
++msgstr "ཁྱོད་ལ་rootཡི་དབང་ཚད་ལྟར་འཁོར་སྐྱོད་བྱེད་དགོས།"
++
++msgid "There is an exception in the update package."
++msgstr "ཁུག་མ་གསར་སྒྱུར་བྱས་པ་རྒྱུན་ལྡན་མིན་པ་ཞིག་རེད"
++
++msgid "You request the removal of a system-essential package."
++msgstr "ཁྱེད་ཀྱིས་མ་ལག་ཅིག་གི་དགོས་ངེས་ཀྱི་མཉེན་ཆས་ཁུག་མ་ཞིག་བསུབ་དགོས་པའི་བླང་བྱ་"
++
++msgid "This update cannot detect the upgradeable package."
++msgstr "ཐེངས་འདིའི་གསར་སྒྱུར་གྱིས་རིམ་འཕར་ཐུབ་པའི་མཉེན་ཆས་ཁུག་མར་ཞིབ་དཔྱད་ཚད་ལེན་བྱེད་ཐབས་མེད།"
++
++msgid "read important list failed"
++msgstr "རིམ་པ་སྤོར་བའི་རེའུ་མིག་ཀློག་ཐབས་བྲལ་བས་རྗེས་སུ་ཡང་བསྐྱར་ཚོད་ལྟ་ཞིག་བྱེད་རོགས།"
++
++msgid "Priority Upgrade Package being updated"
++msgstr "ཁག་བགོས་ཀྱི་བཀོད་སྒྲིག་གསར་སྒྱུར་བྱེད་བཞིན་ཡོད།"
++
++msgid "Exceptions of Priority Upgrade."
++msgstr "དམིགས་སུ་བཀར་ནས་དམིགས་སུ་བཀར་ནས་རིམ་པ"
++
++msgid "Due to the presence of deleted packages."
++msgstr "བསུབ་པའི་མཉེན་ཆས་ཁུག་མ་ཡོད་པའི་རྐྱེན་གྱིས།"
++
++msgid "The system update configuration file is read abnormally, please check if the system update configuration file format is correct."
++msgstr "མ་ལག་གསར་སྒྱུར་བཀོད་སྒྲིག་ཡིག་ཆ་རྒྱུན་ལྡན་མིན་པས། ཞིབ་བཤེར་མ་ལག་གི་བཀོད་སྒྲིག་ཡིག་ཆའི་རྣམ་གཞག་ཡང་དག་ཡིན་མིན་ལ་ཞིབ་བཤེར་གནང་རོགས།"
++
++msgid "Installation progress: "
++msgstr "སྒྲིག་སྦྱོར་མྱུར་ཚད་གཤམ་གསལ། "
++
++msgid "Installation successful, about to shut down"
++msgstr "སྒྲིག་སྦྱོར་ལེགས་འགྲུབ་བྱུང་བ་དང་འགག་སྒོ་ལས་སྒྲོལ་གྲབས་ཡོད་"
++
++msgid "Installation failed, about to shut down"
++msgstr "སྒྲིག་སྦྱོར་བྱས་ནས་ཕམ་ཉེས་བྱུང་ན་སྒོ་རྒྱག་ལ་ཉེ།"
++
++msgid "groups JSON ConfigPkgs install failed"
++msgstr "ཁག་བགོས་ཀྱིས་ཡིག་ཆ་སྒྲིག་སྦྱོར་བྱེད་ཐབས་མེད།"
++
++msgid "Installtion timeout to exit Due to inactivity"
++msgstr "སྒྲིག་སྦྱོར་བྱེད་སྐབས་ཕྱིར་འཐེན་བྱས་པའི་རྐྱེན་གྱིས་རེད།"
++
++msgid "Command execution error"
++msgstr "ཚགས་པར་འདོན་ནོར་ཤོར་བའི་བཀའ་ཕབ་པ།"
++
++msgid "Unsupported architecture"
++msgstr "སྒྲོམ་གཞི་དང་མི་མཐུན་པ།"
++
++msgid "Other Error"
++msgstr "ནོར་འཁྲུལ་གཞན་དག་བཅས་ཡིན"
++
++msgid "dependency is not satisfied"
++msgstr "འབྲེལ་བ་མི་ཚིམ་པར་བརྟེན་དགོས།"
++
++msgid "dependency is not satisfied will download"
++msgstr "འབྲེལ་བ་མི་ཚིམ་པར་བརྟེན་དགོས།"
++
++msgid "Disk space is insufficient, please clean the disk and then upgrade"
++msgstr "ཁབ་ལེན་གྱི་བར་སྟོང་མི་འདང་བས་ཁབ་ལེན་སྡེར་མ་གཙང་བཤེར་བྱས་རྗེས་རིམ་སྤར་གསར་སྒྱུར་བྱེད་རོགས།"
++
++msgid "Network anomaly, can't check for updates!"
++msgstr "དྲ་རྒྱ་རྒྱུན་ལྡན་མིན་པས་ཞིབ་བཤེར་གསར་སྒྱུར་བྱེད་ཐབས་མེད།"
++
++msgid "Check for update exceptions!"
++msgstr "རྒྱུན་ལྡན་མིན་པར་ཞིབ་བཤེར་བྱེད་པ།"
++
++msgid "Check for update exceptions,fix system APT environment error."
++msgstr "ཞིབ་བཤེར་གསར་སྒྱུར་མ་ལག་APTཡི་ཁོར་ཡུག་ལ་ནོར་འཁྲུལ་བྱུང་བ་རེད།"
++
++msgid "The system APT environment is abnormal, please check the system APT environment."
++msgstr "མ་ལག་APTཡི་ཁོར་ཡུག་རྒྱུན་ལྡན་མིན་པར་ཉམས་གསོ་བྱེད་པར་མ་ལག་APTཡི་ཁོར་ཡུག་ལ་ཞིབ་བཤེར་གནང་རོགས།"
++
++msgid "Priority upgrade status exception."
++msgstr "དམིགས་སུ་བཀར་ནས་རིམ་པ་འཕར་བའི་རྣམ་པ་རྒྱུན་ལྡན་མིན་པ"
++
++msgid "Upgrade configuration acquisition exception."
++msgstr "རིམ་སྤར་བཀོད་སྒྲིག་ལ་རྒྱུན་ལྡན་མིན་པའི་གྲུབ་འབྲས་ཐོབ་པ་རེད།"
++
++msgid "Please check your network connection and retry."
++msgstr "ཁྱེད་ཀྱི་དྲ་རྒྱ་འབྲེལ་མཐུད་བྱས་རྗེས་ཡང་བསྐྱར་ཚོད་ལྟ་ཞིག་བྱེད་རོགས།"
++
++msgid "Please check your source list and retry."
++msgstr "ཁྱེད་ཀྱི་འབྱུང་ཁུངས་རེའུ་མིག་ལ་ཞིབ་བཤེར་བྱས་རྗེས་ཡང་བསྐྱར་ཚོད་ལྟ་བྱོས།"
++
++msgid "Checking network connection"
++msgstr "དྲ་རྒྱ་སྦྲེལ་མཐུད་བྱེད་པར་ཞིབ་བཤེར་བྱ་དགོས།"
++
++msgid "Updating Source Template"
++msgstr "འབྱུང་ཁུངས་གསར་སྒྱུར་བྱེད་པའི་མ་དཔེའི་ནང་།"
++
++msgid "Update Manager upgrade is complete, please restart the setting panel before performing the system update."
++msgstr "དོ་དམ་ཡོ་བྱད་རིམ་སྤར་ལེགས་འགྲུབ་བྱུང་བ་དང་། གསར་བཅོས་བྱས་རྗེས་སླར་ཡང་མ་ལག་གསར་སྒྱུར་བྱེད་རོགས།"
++
++msgid "Uninstallation completed"
++msgstr "ཕབ་ལེན་ལེགས་འགྲུབ་བྱུང་བ།"
++
++msgid "Package validation failed and installation was rejected."
++msgstr "མཉེན་ཆས་ཚོད་ལྟས་ར་སྤྲོད་བྱས་ནས་ཕམ་ཁ་བྱུང་བས་སྒྲིག་སྦྱོར་དང་ལེན་མ་བྱས"
++
++msgid "Other tasks are being updated and upgraded, please uninstall them later."
++msgstr "ལས་འགན་གཞན་དག་གསར་སྒྱུར་རིམ་སྤོར་བྱེད་བཞིན་པའི་སྒང་ཡིན་"
++
++#: ../aptdaemon/worker/aptworker.py:1353
++msgid "The following packages have unmet dependencies:"
++msgstr "གཤམ་གསལ་གྱི་མཉེན་ཆས་ཁུག་མ་ཡིད་ཚིམ་པའི་གཞན་རྟེན་གྱི་འབྲེལ་བ།"
++
++#: ../aptdaemon/worker/aptworker.py:1406
++msgid "but it is a virtual package"
++msgstr "འོན་ཀྱང་དེ་ནི་རྟོག་བཟོའི་མཉེན་ཆས་ཁུག་མ་རེད།"
++
++#: ../aptdaemon/worker/aptworker.py:1409
++msgid "but it is not installed"
++msgstr "但是 %s 没有安装"
++
++#: ../aptdaemon/worker/aptworker.py:1411
++msgid "but it is not going to be installed"
++msgstr "但是无法安装 %s"
++
++#. TRANSLATORS: %s is a version number
++#: ../aptdaemon/worker/aptworker.py:1415
++#, python-format
++msgid "but %s is installed"
++msgstr "但是 %s 已经安装"
++
++#. TRANSLATORS: %s is a version number
++#: ../aptdaemon/worker/aptworker.py:1419
++#, python-format
++msgid "but %s is to be installed"
++msgstr "但是将要安装 %s"
++
++#: ../SystemUpdater/Core/enums.py:763
++msgid "Kylin System Updater"
++msgstr "ཝེ།སྒྲིག་ཆས་གསར་སྒྱུར་བྱེད་དགོས།"
++
++#: ../SystemUpdater/Core/enums.py:609
++msgid "Kylin Installer"
++msgstr "ཝེ།སྒྲིག་ཆས་སྒྲིག་སྦྱོར་བྱེད་དགོས།"
++
++#: ../SystemUpdater/Core/enums.py:610
++msgid "Kylin Uninstaller"
++msgstr "ཝེ།བཏགས་ཆས་"
++
++#: ../SystemUpdater/Core/enums.py:611
++msgid "Kylin Background Upgrade"
++msgstr "ཁ་རོག་གེར་གསར་སྒྱུར་བྱེད་པ།"
++
++#: ../SystemUpdater/Core/enums.py:612
++msgid "Kylin Software Center"
++msgstr "མཉེན་ཆས་ཚོང་ཁང་།"
++
++#: ../SystemUpdater/UpdateManagerDbus.py:355
++msgid " requires authentication to uninstall software packages."
++msgstr "མཉེན་ཆས་ཀྱི་ཁུག་མ་འདོན་པར་བདེན་དཔང་ར་སྤྲོད་བྱེད་དགོས།"
++
++#. 验签失败,提权
++#: ../SystemUpdater/UpdateManager.py:463
++msgid " requires authentication to install software packages."
++msgstr "མཉེན་ཆས་ཀྱི་ཁུག་མ་སྒྲིག་སྦྱོར་བྱེད་པར་བདེན་དཔང་ར་སྤྲོད་བྱེད"
++
++#: ../SystemUpdater/Core/utils.py:750
++msgid "Authentication success."
++msgstr "བདེན་དཔང་ར་སྤྲོད་ལེགས་འགྲུབ་བྱུང་"
++
++#: ../SystemUpdater/Core/utils.py:753
++msgid "Authentication failure."
++msgstr "བདེན་དཔང་ར་སྤྲོད་ཕམ་སོང་།"
++
++#: ../SystemUpdater/Core/enums.py:101
++msgid "Deb format exception, read local deb file error."
++msgstr "མཉེན་ཆས་ཀྱི་ཁུག་མའི་རྣམ་གཞག་རྒྱུན་ལྡན་མིན་པས་ཕམ་ཁ་བླངས།"
++
++#: ../SystemUpdater/Core/enums.py:102
++msgid "Install deb error."
++msgstr "མཉེན་ཆས་སྒྲིག་སྦྱོར་བྱས་པ་ཕམ་སོང་།"
++
++msgid "Upgrade System"
++msgstr "ཁྱོན་ཡོངས་ནས་རིམ་སྤར་བྱ་དགོས།"
++
++msgid "kylin-unattended-upgrade"
++msgstr "རང་འགུལ་གྱིས་གསར་སྒྱུར་བྱེད་དགོས།"
++
++msgid "Please check the system time and synchronize the system time before updating."
++msgstr "མ་ལག་གི་དུས་ཚོད་ལ་ཞིབ་བཤེར་གནང་རོགས། དུས་མཉམ་དུ་མ་ལག་གི་དུས་ཚོད་རྗེས་སུ་གསར་སྒྱུར་བྱེད་དགོས"
++
++msgid "The package is unsigned, refuses to install."
++msgstr "མཉེན་ཆས་ཀྱི་ཁུག་མར་མིང་རྟགས་མ་བཀོད་པས་སྒྲིག་སྦྱོར་དང་ལེན་མི་བྱེད།"
++
++msgid "Program exception, please contact the administrator to solve."
++msgstr "གོ་རིམ་ལག་བསྟར་རྒྱུན་ལྡན་མིན་པར་དོ་དམ་པ་དང་འབྲེལ་གཏུག་བྱས་ནས་ཐག་གཅོད"
++
++msgid "Exceptions to running the check script."
++msgstr "འཁོར་སྐྱོད་ཞིབ་བཤེར་གྱི་རྐང་པར་རྒྱུན་ལྡན་མིན་པ་བྱུང་།"
++
++msgid "Application installation control policy not enabled ."
++msgstr "ཉེར་སྤྱོད་སྒྲིག་སྦྱོར་དོ་དམ་ཚོད་འཛིན་བྱེད་འགོ་ཚུགས་མེད་པ།"
++
++msgid "Installation failed! Application is not in the software whitelist list!"
++msgstr "སྒྲིག་སྦྱོར་ཕམ་པ། མཉེན་ཆས་ནི་མིང་ཐོའི་རེའུ་མིག་དཀར་པོ་ན་ཡོད་དམ།"
++
++msgid "Installation failed! Application is in the software blacklist list!"
++msgstr "སྒྲིག་སྦྱོར་ཕམ་པ། མཉེན་ཆས་མིང་ཐོའི་ནང་དུ་ཡོད།"
++
++msgid "Application installation in unknown mode ."
++msgstr "ཉེར་སྤྱོད་སྒྲིག་སྦྱོར་དང་དོ་དམ་ཚོད་འཛིན་གྱི་ཐབས་ཇུས་མི་ཤེས་པ།"
++
++#: ../SystemUpdater/Core/utils.py:753
++msgid "Cancel authentication."
++msgstr "ཕྱིར་འབུད་བྱ་རྒྱུ།"
+diff --git a/backend-immutable/tests/po/zh_CN.po b/backend-immutable/tests/po/zh_CN.po
+new file mode 100644
+index 0000000..9a401f2
+--- /dev/null
++++ b/backend-immutable/tests/po/zh_CN.po
+@@ -0,0 +1,2821 @@
++# SOME DESCRIPTIVE TITLE.
++# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
++# This file is distributed under the same license as the PACKAGE package.
++# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
++#
++#, fuzzy
++msgid ""
++msgstr ""
++"Project-Id-Version: PACKAGE VERSION\n"
++"Report-Msgid-Bugs-To: sebastian.heinlein@web.de\n"
++"POT-Creation-Date: 2012-06-14 00:53+0100\n"
++"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
++"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
++"Language-Team: LANGUAGE <LL@li.org>\n"
++"Language: \n"
++"MIME-Version: 1.0\n"
++"Content-Type: text/plain; charset=UTF-8\n"
++"Content-Transfer-Encoding: 8bit\n"
++
++#. TRANSLATORS: download size of small updates, e.g. "250 kB"
++#: ../DistUpgrade/utils.py:433 ../UpdateManager/Core/utils.py:433
++#, python-format
++msgid "%(size).0f kB"
++msgid_plural "%(size).0f kB"
++msgstr[0] "%(size).0f kB"
++
++#. TRANSLATORS: download size of updates, e.g. "2.3 MB"
++#: ../DistUpgrade/utils.py:436 ../UpdateManager/Core/utils.py:436
++#, python-format
++msgid "%.1f MB"
++msgstr "%.1f MB"
++
++#. TRANSLATORS: %s is a country
++#: ../DistUpgrade/distro.py:206 ../DistUpgrade/distro.py:436
++#, python-format
++msgid "Server for %s"
++msgstr "%s 的服务器"
++
++#. More than one server is used. Since we don't handle this case
++#. in the user interface we set "custom servers" to true and
++#. append a list of all used servers
++#: ../DistUpgrade/distro.py:224 ../DistUpgrade/distro.py:230
++#: ../DistUpgrade/distro.py:246
++msgid "Main server"
++msgstr "主服务器"
++
++#: ../DistUpgrade/distro.py:250
++msgid "Custom servers"
++msgstr "自定义服务器"
++
++#: ../DistUpgrade/DistUpgradeAptCdrom.py:142
++msgid "Could not calculate sources.list entry"
++msgstr "无法计算 sources.list 条目"
++
++#: ../DistUpgrade/DistUpgradeAptCdrom.py:251
++msgid ""
++"Unable to locate any package files, perhaps this is not a Ubuntu Disc or the "
++"wrong architecture?"
++msgstr "无法定位任何软件包文件,也许这张不是 Ubuntu 光盘,或者其架构错误?"
++
++#: ../DistUpgrade/DistUpgradeAptCdrom.py:294
++msgid "Failed to add the CD"
++msgstr "添加 CD 失败"
++
++#: ../DistUpgrade/DistUpgradeAptCdrom.py:295
++#, python-format
++msgid ""
++"There was a error adding the CD, the upgrade will abort. Please report this "
++"as a bug if this is a valid Ubuntu CD.\n"
++"\n"
++"The error message was:\n"
++"'%s'"
++msgstr ""
++"添加 CD 时出错,升级中止。如果这是一张有效的 Ubuntu CD,请您报告这个错误。\n"
++"\n"
++"错误信息是:\n"
++"'%s'"
++
++#: ../DistUpgrade/DistUpgradeCache.py:151
++msgid "Remove package in bad state"
++msgid_plural "Remove packages in bad state"
++msgstr[0] "卸载状态异常的软件包"
++
++#: ../DistUpgrade/DistUpgradeCache.py:154
++#, python-format
++msgid ""
++"The package '%s' is in an inconsistent state and needs to be reinstalled, "
++"but no archive can be found for it. Do you want to remove this package now "
++"to continue?"
++msgid_plural ""
++"The packages '%s' are in an inconsistent state and need to be reinstalled, "
++"but no archives can be found for them. Do you want to remove these packages "
++"now to continue?"
++msgstr[0] ""
++"软件包“%s”处于不一致的状态,需要重新安装,但是没有找到对应的存档。您希望现在"
++"删除这个软件包以进行下一步吗?"
++
++#. FIXME: not ideal error message, but we just reuse a
++#. existing one here to avoid a new string
++#: ../DistUpgrade/DistUpgradeCache.py:255
++msgid "The server may be overloaded"
++msgstr "服务器可能已过载"
++
++#: ../DistUpgrade/DistUpgradeCache.py:368
++msgid "Broken packages"
++msgstr "破损的软件包"
++
++#: ../DistUpgrade/DistUpgradeCache.py:369
++msgid ""
++"Your system contains broken packages that couldn't be fixed with this "
++"software. Please fix them first using synaptic or apt-get before proceeding."
++msgstr ""
++"您的系统包含有本软件不能修复的破损软件包,在您继续前请先用新立得或者 apt-get "
++"修复它们。"
++
++#. FIXME: change the text to something more useful
++#: ../DistUpgrade/DistUpgradeCache.py:693
++#, python-format
++msgid ""
++"An unresolvable problem occurred while calculating the upgrade:\n"
++"%s\n"
++"\n"
++" This can be caused by:\n"
++" * Upgrading to a pre-release version of Ubuntu\n"
++" * Running the current pre-release version of Ubuntu\n"
++" * Unofficial software packages not provided by Ubuntu\n"
++"\n"
++msgstr ""
++"在准备升级时发生了一个无法解决的问题:\n"
++"%s\n"
++"\n"
++" 这可能是由以下原因引起的:\n"
++" * 升级到了预发行 Ubuntu 版本\n"
++" * 正在运行当前的预发行 Ubuntu 版本\n"
++" * 非 Ubuntu 提供的非官方软件包\n"
++"\n"
++
++#: ../DistUpgrade/DistUpgradeCache.py:703
++msgid "This is most likely a transient problem, please try again later."
++msgstr "很可能发生了一个传输问题,请稍后重试。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:706
++msgid ""
++"If none of this applies, then please report this bug using the command "
++"'ubuntu-bug update-manager' in a terminal."
++msgstr ""
++"如果没有应用任何变更,您可以在终端里输入命令‘ubuntu-bug update-manager’来报告"
++"这个 bug。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:711
++#: ../UpdateManager/UpdateManager.py:1031
++msgid "Could not calculate the upgrade"
++msgstr "不能计算升级"
++
++#: ../DistUpgrade/DistUpgradeCache.py:762
++msgid "Error authenticating some packages"
++msgstr "一些软件包认证出错"
++
++#: ../DistUpgrade/DistUpgradeCache.py:763
++msgid ""
++"It was not possible to authenticate some packages. This may be a transient "
++"network problem. You may want to try again later. See below for a list of "
++"unauthenticated packages."
++msgstr ""
++"一些软件包无法通过签名验证。这可能是暂时的网络问题,您可以在稍后再试。以下是"
++"未认证软件包的列表。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:783
++#, python-format
++msgid ""
++"The package '%s' is marked for removal but it is in the removal blacklist."
++msgstr "软件包“%s”标记为可移除,但它已在移除黑名单中。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:787
++#, python-format
++msgid "The essential package '%s' is marked for removal."
++msgstr "必要的软件包“%s”被标记为移除。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:796
++#, python-format
++msgid "Trying to install blacklisted version '%s'"
++msgstr "尝试安装黑名单版本“%s”"
++
++#: ../DistUpgrade/DistUpgradeCache.py:914
++#, python-format
++msgid "Can't install '%s'"
++msgstr "无法安装 '%s'"
++
++#: ../DistUpgrade/DistUpgradeCache.py:915
++msgid ""
++"It was impossible to install a required package. Please report this as a bug "
++"using 'ubuntu-bug update-manager' in a terminal."
++msgstr ""
++"无法安装一个必需的软件包。请在终端里输入命令‘ubuntu-bug update-manager’来报告"
++"这个 bug。"
++
++#. FIXME: provide a list
++#: ../DistUpgrade/DistUpgradeCache.py:926
++msgid "Can't guess meta-package"
++msgstr "无法猜出元软件包"
++
++#: ../DistUpgrade/DistUpgradeCache.py:927
++msgid ""
++"Your system does not contain a ubuntu-desktop, kubuntu-desktop, xubuntu-"
++"desktop or edubuntu-desktop package and it was not possible to detect which "
++"version of Ubuntu you are running.\n"
++" Please install one of the packages above first using synaptic or apt-get "
++"before proceeding."
++msgstr ""
++"您的系统没有安装 ubuntu-desktop,kubuntu-desktop 或 eubuntu-desktop 软件包所"
++"以无法确定运行的 ubuntu 的版本。\n"
++" 请先用新立得或 APT 安装以上所举软件包中的一个。"
++
++#: ../DistUpgrade/DistUpgradeController.py:114
++msgid "Reading cache"
++msgstr "正在读取缓存"
++
++#: ../DistUpgrade/DistUpgradeController.py:223
++msgid "Unable to get exclusive lock"
++msgstr "无法获得排它锁"
++
++#: ../DistUpgrade/DistUpgradeController.py:224
++msgid ""
++"This usually means that another package management application (like apt-get "
++"or aptitude) already running. Please close that application first."
++msgstr ""
++"这通常意味着另一个软件包管理程序(如 apt-get 或 aptitude)正在运行。请先关闭那"
++"个程序。"
++
++#: ../DistUpgrade/DistUpgradeController.py:257
++msgid "Upgrading over remote connection not supported"
++msgstr "不支持通过远程连接升级"
++
++#: ../DistUpgrade/DistUpgradeController.py:258
++msgid ""
++"You are running the upgrade over a remote ssh connection with a frontend "
++"that does not support this. Please try a text mode upgrade with 'do-release-"
++"upgrade'.\n"
++"\n"
++"The upgrade will abort now. Please try without ssh."
++msgstr ""
++"您正在通过远程 SSH 升级,而前端程序不支持这种方式。请尝试在文本模式下通过 "
++"'do-release-upgrade' 命令进行升级。\n"
++"\n"
++"现在将退出升级。请试试不使用 ssh 的方式。"
++
++#: ../DistUpgrade/DistUpgradeController.py:272
++msgid "Continue running under SSH?"
++msgstr "继续在 SSH 下执行?"
++
++#: ../DistUpgrade/DistUpgradeController.py:273
++#, python-format
++msgid ""
++"This session appears to be running under ssh. It is not recommended to "
++"perform a upgrade over ssh currently because in case of failure it is harder "
++"to recover.\n"
++"\n"
++"If you continue, an additional ssh daemon will be started at port '%s'.\n"
++"Do you want to continue?"
++msgstr ""
++"此会话似乎是在 SSH 下运行。目前不推荐通过 SSH 执行升级,因为升级失败时较难恢"
++"复。\n"
++"\n"
++"如果您选择继续,将在 '%s' 端口上建立额外的 SSH 守护进程。\n"
++"您想要继续吗?"
++
++#: ../DistUpgrade/DistUpgradeController.py:287
++msgid "Starting additional sshd"
++msgstr "正在启用额外的 ssh 守护进程"
++
++#: ../DistUpgrade/DistUpgradeController.py:288
++#, python-format
++msgid ""
++"To make recovery in case of failure easier, an additional sshd will be "
++"started on port '%s'. If anything goes wrong with the running ssh you can "
++"still connect to the additional one.\n"
++msgstr ""
++"为了在失败时更容易恢复,将在端口“%s”开启一个额外的 ssh 守护进程。如果当前运行"
++"的 ssh 发生错误,您仍能够通过该额外的 ssh 进行连接。\n"
++
++#: ../DistUpgrade/DistUpgradeController.py:296
++#, python-format
++msgid ""
++"If you run a firewall, you may need to temporarily open this port. As this "
++"is potentially dangerous it's not done automatically. You can open the port "
++"with e.g.:\n"
++"'%s'"
++msgstr ""
++"如果您运行了一个防火墙,可能需要临时打开这个端口。这可能有些危险,因此没有自"
++"动进行这个操作。您可以通过类似这样的命令打开端口:\n"
++"%s"
++
++#: ../DistUpgrade/DistUpgradeController.py:368
++#: ../DistUpgrade/DistUpgradeController.py:413
++msgid "Can not upgrade"
++msgstr "不能升级"
++
++#: ../DistUpgrade/DistUpgradeController.py:369
++#, python-format
++msgid "An upgrade from '%s' to '%s' is not supported with this tool."
++msgstr "此工具不支持从 '%s' 到 ‘%s' 的升级。"
++
++#: ../DistUpgrade/DistUpgradeController.py:378
++msgid "Sandbox setup failed"
++msgstr "安装沙盒失败"
++
++#: ../DistUpgrade/DistUpgradeController.py:379
++msgid "It was not possible to create the sandbox environment."
++msgstr "不能创建沙盒环境"
++
++#: ../DistUpgrade/DistUpgradeController.py:385
++msgid "Sandbox mode"
++msgstr "沙盒模式"
++
++#: ../DistUpgrade/DistUpgradeController.py:386
++#, python-format
++msgid ""
++"This upgrade is running in sandbox (test) mode. All changes are written to "
++"'%s' and will be lost on the next reboot.\n"
++"\n"
++"*No* changes written to a system directory from now until the next reboot "
++"are permanent."
++msgstr ""
++"本次更新运行在沙盘(测试)模式,所有变更都将写入 '%s' 并会在重启后丢失。\n"
++"\n"
++"从现在起对系统目录的变更重启后都将 *不复存在* 。"
++
++#: ../DistUpgrade/DistUpgradeController.py:414
++msgid ""
++"Your python install is corrupted. Please fix the '/usr/bin/python' symlink."
++msgstr "您的 python 安装错误,请修复“/usr/bin/python”符号链接。"
++
++#: ../DistUpgrade/DistUpgradeController.py:440
++msgid "Package 'debsig-verify' is installed"
++msgstr "已安装软件包“debsig-verify”"
++
++#: ../DistUpgrade/DistUpgradeController.py:441
++msgid ""
++"The upgrade can not continue with that package installed.\n"
++"Please remove it with synaptic or 'apt-get remove debsig-verify' first and "
++"run the upgrade again."
++msgstr ""
++"由于安装了上述软件包而无法继续升级。\n"
++"请使用新立得软件包管理器来移除它,或者先使用 “sudo apt-get remove debsig-"
++"verify”卸载后再重新尝试升级。"
++
++#: ../DistUpgrade/DistUpgradeController.py:453
++#, python-format
++msgid "Can not write to '%s'"
++msgstr "无法写入 '%s'"
++
++#: ../DistUpgrade/DistUpgradeController.py:454
++#, python-format
++msgid ""
++"Its not possible to write to the system directory '%s' on your system. The "
++"upgrade can not continue.\n"
++"Please make sure that the system directory is writable."
++msgstr ""
++"无法写入您的系统目录 %s ,升级无法继续。\n"
++"请确保系统目录可写。"
++
++#: ../DistUpgrade/DistUpgradeController.py:465
++msgid "Include latest updates from the Internet?"
++msgstr "包括网络上的最新更新?"
++
++#: ../DistUpgrade/DistUpgradeController.py:466
++msgid ""
++"The upgrade system can use the internet to automatically download the latest "
++"updates and install them during the upgrade.  If you have a network "
++"connection this is highly recommended.\n"
++"\n"
++"The upgrade will take longer, but when it is complete, your system will be "
++"fully up to date.  You can choose not to do this, but you should install the "
++"latest updates soon after upgrading.\n"
++"If you answer 'no' here, the network is not used at all."
++msgstr ""
++"升级系统能够从网络上自动下载最新的更新文件并自动安装。如果网络连接可用,强烈"
++"建议启用此选项。\n"
++"\n"
++"升级时间可能加长,但升级结束后,您的系统将是最新的。您也可以选择在升级结束后"
++"再进行系统更新。\n"
++"如果选择\"否\",就不会使用网络。"
++
++#: ../DistUpgrade/DistUpgradeController.py:686
++#, python-format
++msgid "disabled on upgrade to %s"
++msgstr "已禁止升级到 %s"
++
++#: ../DistUpgrade/DistUpgradeController.py:713
++msgid "No valid mirror found"
++msgstr "未找到可用的镜像"
++
++#: ../DistUpgrade/DistUpgradeController.py:714
++#, python-format
++msgid ""
++"While scanning your repository information no mirror entry for the upgrade "
++"was found. This can happen if you run a internal mirror or if the mirror "
++"information is out of date.\n"
++"\n"
++"Do you want to rewrite your 'sources.list' file anyway? If you choose 'Yes' "
++"here it will update all '%s' to '%s' entries.\n"
++"If you select 'No' the upgrade will cancel."
++msgstr ""
++"扫描仓库时未发现升级信息。可能您使用的是内部镜像或者镜像信息已经过期。\n"
++"\n"
++"是否依然重写 \"sources.list\" 文件?如果选择“是”,将会把所有 “%s” 升级到 "
++"“%s”。"
++
++#. hm, still nothing useful ...
++#: ../DistUpgrade/DistUpgradeController.py:734
++msgid "Generate default sources?"
++msgstr "生成默认的源?"
++
++#: ../DistUpgrade/DistUpgradeController.py:735
++#, python-format
++msgid ""
++"After scanning your 'sources.list' no valid entry for '%s' was found.\n"
++"\n"
++"Should default entries for '%s' be added? If you select 'No', the upgrade "
++"will cancel."
++msgstr ""
++"扫描“sources.list”后未发现用于“%s”的可用项。\n"
++"\n"
++"是否为“%s”添加默认项?如果选择“否”,将会取消升级。"
++
++#: ../DistUpgrade/DistUpgradeController.py:770
++msgid "Repository information invalid"
++msgstr "仓库信息无效"
++
++#: ../DistUpgrade/DistUpgradeController.py:771
++msgid ""
++"Upgrading the repository information resulted in a invalid file so a bug "
++"reporting process is being started."
++msgstr "更新软件源时返回了无效文件,已启动错误报告进程。"
++
++#: ../DistUpgrade/DistUpgradeController.py:778
++msgid "Third party sources disabled"
++msgstr "第三方源被禁用"
++
++#: ../DistUpgrade/DistUpgradeController.py:779
++msgid ""
++"Some third party entries in your sources.list were disabled. You can re-"
++"enable them after the upgrade with the 'software-properties' tool or your "
++"package manager."
++msgstr ""
++"您的 sources.list 中的一些第三方源被禁用。您可以在升级后用\"软件源\"工具或包"
++"管理器来重新启用它们。"
++
++#: ../DistUpgrade/DistUpgradeController.py:819
++msgid "Package in inconsistent state"
++msgid_plural "Packages in inconsistent state"
++msgstr[0] "软件包存在冲突"
++
++#: ../DistUpgrade/DistUpgradeController.py:822
++#, python-format
++msgid ""
++"The package '%s' is in an inconsistent state and needs to be reinstalled, "
++"but no archive can be found for it. Please reinstall the package manually or "
++"remove it from the system."
++msgid_plural ""
++"The packages '%s' are in an inconsistent state and need to be reinstalled, "
++"but no archive can be found for them. Please reinstall the packages manually "
++"or remove them from the system."
++msgstr[0] ""
++"软件包“%s”处于冲突状态,需要重新安装, 但是没能找到它的存档。请重新手动安装这"
++"个软件包或者将其从系统中删除。"
++
++#: ../DistUpgrade/DistUpgradeController.py:870
++msgid "Error during update"
++msgstr "升级时出错"
++
++#: ../DistUpgrade/DistUpgradeController.py:871
++msgid ""
++"A problem occurred during the update. This is usually some sort of network "
++"problem, please check your network connection and retry."
++msgstr "升级过程中出错。这通常是一些网络问题,请检查您的网络连接后再试"
++
++#. print("on_button_install_clicked")
++#: ../DistUpgrade/DistUpgradeController.py:880
++#: ../UpdateManager/UpdateManager.py:757
++msgid "Not enough free disk space"
++msgstr "磁盘空间不足"
++
++#: ../DistUpgrade/DistUpgradeController.py:881
++#, python-format
++msgid ""
++"The upgrade has aborted. The upgrade needs a total of %s free space on disk "
++"'%s'. Please free at least an additional %s of disk space on '%s'. Empty "
++"your trash and remove temporary packages of former installations using 'sudo "
++"apt-get clean'."
++msgstr ""
++"升级已被中断。此次升级需要有 %s 的可用空间在磁盘 %s 上。请释放至少 %s 的空间"
++"在磁盘 %s 上。您可以清空回收站并使用“sudo apt-get clean”命令以清除之前安装操"
++"作留下的临时文件。"
++
++#. calc the dist-upgrade and see if the removals are ok/expected
++#. do the dist-upgrade
++#: ../DistUpgrade/DistUpgradeController.py:910
++#: ../DistUpgrade/DistUpgradeController.py:1692
++msgid "Calculating the changes"
++msgstr "正在计算变更"
++
++#. ask the user
++#: ../DistUpgrade/DistUpgradeController.py:942
++msgid "Do you want to start the upgrade?"
++msgstr "您要开始升级么?"
++
++#: ../DistUpgrade/DistUpgradeController.py:1008
++msgid "Upgrade canceled"
++msgstr "升级已取消"
++
++#: ../DistUpgrade/DistUpgradeController.py:1009
++msgid ""
++"The upgrade will cancel now and the original system state will be restored. "
++"You can resume the upgrade at a later time."
++msgstr "升级将会取消,系统会恢复到原始状态。您可以在之后继续升级。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1015
++#: ../DistUpgrade/DistUpgradeController.py:1149
++msgid "Could not download the upgrades"
++msgstr "无法下载升级包"
++
++#: ../DistUpgrade/DistUpgradeController.py:1016
++msgid ""
++"The upgrade has aborted. Please check your Internet connection or "
++"installation media and try again. All files downloaded so far have been kept."
++msgstr ""
++"已中止升级。请检查您的互联网连接或安装媒体并重试。所有已下载的文件都已保存。"
++
++#. FIXME: strings are not good, but we are in string freeze
++#. currently
++#: ../DistUpgrade/DistUpgradeController.py:1100
++#: ../DistUpgrade/DistUpgradeController.py:1137
++#: ../DistUpgrade/DistUpgradeController.py:1242
++msgid "Error during commit"
++msgstr "确认时出错"
++
++#. generate a new cache
++#: ../DistUpgrade/DistUpgradeController.py:1102
++#: ../DistUpgrade/DistUpgradeController.py:1139
++#: ../DistUpgrade/DistUpgradeController.py:1281
++msgid "Restoring original system state"
++msgstr "正在恢复原始系统状态"
++
++#: ../DistUpgrade/DistUpgradeController.py:1103
++#: ../DistUpgrade/DistUpgradeController.py:1118
++#: ../DistUpgrade/DistUpgradeController.py:1140
++msgid "Could not install the upgrades"
++msgstr "无法安装升级"
++
++#. invoke the frontend now and show a error message
++#: ../DistUpgrade/DistUpgradeController.py:1108
++msgid ""
++"The upgrade has aborted. Your system could be in an unusable state. A "
++"recovery will run now (dpkg --configure -a)."
++msgstr ""
++"更新已取消。您的系统可能处在不稳定状态。正在恢复 (dpkg --configure -a)。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1113
++#, python-format
++msgid ""
++"\n"
++"\n"
++"Please report this bug in a browser at http://bugs.launchpad.net/ubuntu/"
++"+source/update-manager/+filebug and attach the files in /var/log/dist-"
++"upgrade/ to the bug report.\n"
++"%s"
++msgstr ""
++"\n"
++"\n"
++"请使用浏览器在 http://bugs.launchpad.net/ubuntu/+source/update-manager/"
++"+filebug 中报告此错误,然后随错误报告附上 /var/log/dist-upgrade/ 中的文件。\n"
++"%s"
++
++#: ../DistUpgrade/DistUpgradeController.py:1150
++msgid ""
++"The upgrade has aborted. Please check your Internet connection or "
++"installation media and try again. "
++msgstr "更新已取消。请检查您的因特网连接或安装媒体,然后再试一遍。 "
++
++#: ../DistUpgrade/DistUpgradeController.py:1230
++msgid "Remove obsolete packages?"
++msgstr "删除陈旧的软件包?"
++
++#: ../DistUpgrade/DistUpgradeController.py:1231
++#: ../DistUpgrade/DistUpgrade.ui.h:8
++msgid "_Keep"
++msgstr "保持(_K)"
++
++#: ../DistUpgrade/DistUpgradeController.py:1231
++msgid "_Remove"
++msgstr "删除(_R)"
++
++#: ../DistUpgrade/DistUpgradeController.py:1243
++msgid ""
++"A problem occurred during the clean-up. Please see the below message for "
++"more information. "
++msgstr "清理时出现问题。更多信息请查看以下消息。 "
++
++#. FIXME: instead of error out, fetch and install it
++#. here
++#: ../DistUpgrade/DistUpgradeController.py:1319
++msgid "Required depends is not installed"
++msgstr "需要的依赖关系未安装"
++
++#: ../DistUpgrade/DistUpgradeController.py:1320
++#, python-format
++msgid "The required dependency '%s' is not installed. "
++msgstr "需要的依赖关系“%s”未安装 。 "
++
++#. sanity check (check for ubuntu-desktop, brokenCache etc)
++#. then open the cache (again)
++#: ../DistUpgrade/DistUpgradeController.py:1588
++#: ../DistUpgrade/DistUpgradeController.py:1653
++msgid "Checking package manager"
++msgstr "正在检查软件包管理器"
++
++#: ../DistUpgrade/DistUpgradeController.py:1593
++msgid "Unable to get group configuration package, Please check if the configuration package exists in the software source repository."
++msgstr "无法获取组配置软件包,请检查组配置包是否存在软件源仓库中。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1593
++msgid "Unable to install group configuration package, Please check the configuration package related dependencies."
++msgstr "无法安装组配置包,请检查组配置包相关依赖。"
++
++msgid "Unable to perform priority upgrade, please check the dependency related to the priority upgrade package."
++msgstr "无法进行优先升级,请检查优先升级包相关依赖。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1594
++msgid ""
++"Preparing the system for the upgrade failed so a bug reporting process is "
++"being started."
++msgstr "更新时的系统准备失败,已启动错误报告进程。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1608
++msgid "Getting upgrade prerequisites failed"
++msgstr "准备升级失败"
++
++#: ../DistUpgrade/DistUpgradeController.py:1609
++msgid ""
++"The system was unable to get the prerequisites for the upgrade. The upgrade "
++"will abort now and restore the original system state.\n"
++"\n"
++"Additionally, a bug reporting process is being started."
++msgstr ""
++"系统不能满足升级先决条件。现在会中止升级并恢复原来的系统状态。\n"
++"\n"
++"此外,错误报告进程也将启动。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1637
++msgid "Updating repository information"
++msgstr "正在更新软件仓库信息"
++
++#: ../DistUpgrade/DistUpgradeController.py:1644
++msgid "Failed to add the cdrom"
++msgstr "添加光驱失败"
++
++#: ../DistUpgrade/DistUpgradeController.py:1645
++msgid "Sorry, adding the cdrom was not successful."
++msgstr "对不起,没有成功添加光驱。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1673
++msgid "Invalid package information"
++msgstr "无效的软件包信息"
++
++#: ../DistUpgrade/DistUpgradeController.py:1674
++msgid "After updating your package "
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeController.py:1698
++#: ../DistUpgrade/DistUpgradeController.py:1750
++msgid "Fetching"
++msgstr "正在获取"
++
++#: ../DistUpgrade/DistUpgradeController.py:1704
++#: ../DistUpgrade/DistUpgradeController.py:1754
++msgid "Upgrading"
++msgstr "正在升级"
++
++#. don't abort here, because it would restore the sources.list
++#: ../DistUpgrade/DistUpgradeController.py:1709
++#: ../DistUpgrade/DistUpgradeController.py:1756
++#: ../DistUpgrade/DistUpgradeController.py:1763
++#: ../DistUpgrade/DistUpgradeController.py:1774
++msgid "Upgrade complete"
++msgstr "升级完成"
++
++#: ../DistUpgrade/DistUpgradeController.py:1710
++#: ../DistUpgrade/DistUpgradeController.py:1757
++#: ../DistUpgrade/DistUpgradeController.py:1764
++msgid ""
++"The upgrade has completed but there were errors during the upgrade process."
++msgstr "升级已完成,但其间出现错误。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1717
++msgid "Searching for obsolete software"
++msgstr "正在搜索废弃的软件"
++
++#: ../DistUpgrade/DistUpgradeController.py:1726
++msgid "System upgrade is complete."
++msgstr "系统升级完成。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1775
++msgid "The partial upgrade was completed."
++msgstr "部分升级完成。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:204
++msgid "evms in use"
++msgstr "evms 使用中"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:205
++msgid ""
++"Your system uses the 'evms' volume manager in /proc/mounts. The 'evms' "
++"software is no longer supported, please switch it off and run the upgrade "
++"again when this is done."
++msgstr ""
++"您的系统在 /proc/mounts 中使用“evms”卷管理器。“evms”软件不再被支持,请关闭它"
++"并重新运行升级。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:502
++msgid "Your graphics hardware may not be fully supported in Ubuntu 12.04 LTS."
++msgstr "Ubuntu 12.04 LTS 可能无法完全支持您的显卡。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:504
++msgid ""
++"The support in Ubuntu 12.04 LTS for your Intel graphics hardware is limited "
++"and you may encounter problems after the upgrade. For more information see "
++"https://wiki.ubuntu.com/X/Bugs/UpdateManagerWarningForI8xx Do you want to "
++"continue with the upgrade?"
++msgstr ""
++"Ubuntu 12.04 LTS 对 Intel 图形硬件的支持有限制,升级后您可能会遭遇问题。更多"
++"信息,请查看 https://wiki.ubuntu.com/X/Bugs/UpdateManagerWarningForI8xx 。仍"
++"然想要继续升级吗?"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:526
++#: ../DistUpgrade/DistUpgradeQuirks.py:554
++#: ../DistUpgrade/DistUpgradeQuirks.py:581
++msgid ""
++"Upgrading may reduce desktop effects, and performance in games and other "
++"graphically intensive programs."
++msgstr "升级过程可能会降低桌面特效,游戏性能以及对显示要求高的程序。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:530
++#: ../DistUpgrade/DistUpgradeQuirks.py:558
++msgid ""
++"This computer is currently using the NVIDIA 'nvidia' graphics driver. No "
++"version of this driver is available that works with your video card in "
++"Ubuntu 10.04 LTS.\n"
++"\n"
++"Do you want to continue?"
++msgstr ""
++"此计算机正在使用 NVIDIA “nvidia”显卡驱动。该驱动在 Ubuntu 10.04 LTS 中没有与"
++"您的硬件相适应的版本。\n"
++"\n"
++"您想继续吗?"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:585
++msgid ""
++"This computer is currently using the AMD 'fglrx' graphics driver. No version "
++"of this driver is available that works with your hardware in Ubuntu 10.04 "
++"LTS.\n"
++"\n"
++"Do you want to continue?"
++msgstr ""
++"此计算机正在使用 AMD “fglrx”显卡驱动。该驱动在 Ubuntu 10.04 LTS 中没有与您的"
++"硬件相适应的版本。\n"
++"\n"
++"您想继续吗?"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:615
++msgid "No i686 CPU"
++msgstr "非 i686 CPU"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:616
++msgid ""
++"Your system uses an i586 CPU or a CPU that does not have the 'cmov' "
++"extension. All packages were built with optimizations requiring i686 as the "
++"minimal architecture. It is not possible to upgrade your system to a new "
++"Ubuntu release with this hardware."
++msgstr ""
++"您的系统使用的是 i586 或是没有“cmov”扩展的 CPU。所有优化生成的软件包都需要最"
++"低 i686 的架构。这样的硬件无法升级到新的 Ubuntu 发行版。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:652
++msgid "No ARMv6 CPU"
++msgstr "没有 ARMv6 CPU"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:653
++msgid ""
++"Your system uses an ARM CPU that is older than the ARMv6 architecture. All "
++"packages in karmic were built with optimizations requiring ARMv6 as the "
++"minimal architecture. It is not possible to upgrade your system to a new "
++"Ubuntu release with this hardware."
++msgstr ""
++"您的系统使用的是比 ARMv6 架构旧的 ARM CPU。karmic 中所有软件包构建时进行的优"
++"化都需要至少 ARMv6 的 CPU 架构。在这种硬件基础上无法将您的系统升级到一个新的 "
++"Ubuntu 发行版。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:673
++msgid "No init available"
++msgstr "无可用的 init"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:674
++msgid ""
++"Your system appears to be a virtualised environment without an init daemon, "
++"e.g. Linux-VServer. Ubuntu 10.04 LTS cannot function within this type of "
++"environment, requiring an update to your virtual machine configuration "
++"first.\n"
++"\n"
++"Are you sure you want to continue?"
++msgstr ""
++"您的系统似乎运行在一个没有 init daemon 的虚拟化环境中(如 Linux-VServer),"
++"Ubuntu 10.04 LTS 无法在这种环境中运行,您需要先更新您的虚拟机配置。\n"
++"\n"
++"您确定要继续吗?"
++
++#: ../DistUpgrade/DistUpgradeMain.py:65
++msgid "Sandbox upgrade using aufs"
++msgstr "使用 aufs 进行沙盒升级"
++
++#: ../DistUpgrade/DistUpgradeMain.py:67
++msgid "Use the given path to search for a cdrom with upgradable packages"
++msgstr "使用所给的路径查找带升级包的 CD-ROM"
++
++#: ../DistUpgrade/DistUpgradeMain.py:73
++msgid ""
++"Use frontend. Currently available: \n"
++"DistUpgradeViewText, DistUpgradeViewGtk, DistUpgradeViewKDE"
++msgstr ""
++"使用前端。当前可用的有: \n"
++"DistUpgradeViewText, DistUpgradeViewGtk, DistUpgradeViewKDE"
++
++#: ../DistUpgrade/DistUpgradeMain.py:76
++msgid "*DEPRECATED* this option will be ignored"
++msgstr "*已废弃* 这个选项将被忽略"
++
++#: ../DistUpgrade/DistUpgradeMain.py:79
++msgid "Perform a partial upgrade only (no sources.list rewriting)"
++msgstr "仅执行部分升级(不重写 sources.list)"
++
++#: ../DistUpgrade/DistUpgradeMain.py:82
++msgid "Disable GNU screen support"
++msgstr "关闭对 GNU screen 的支持"
++
++#: ../DistUpgrade/DistUpgradeMain.py:84
++msgid "Set datadir"
++msgstr "设置数据目录"
++
++#. print("mediaChange %s %s" % (medium, drive))
++#: ../DistUpgrade/DistUpgradeViewGtk.py:114
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:117
++#: ../DistUpgrade/DistUpgradeViewKDE.py:195
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:155
++#, python-format
++msgid "Please insert '%s' into the drive '%s'"
++msgstr "请将 '%s' 插入光驱 '%s'"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:135
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:138
++#: ../DistUpgrade/DistUpgradeViewKDE.py:209
++msgid "Fetching is complete"
++msgstr "下载完成"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:146
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:149
++#: ../DistUpgrade/DistUpgradeViewKDE.py:222
++#, python-format
++msgid "Fetching file %li of %li at %sB/s"
++msgstr "正在下载文件 %li/%li 速度 %s/s"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:149
++#: ../DistUpgrade/DistUpgradeViewGtk.py:296
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:152
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:309
++#: ../DistUpgrade/DistUpgradeViewKDE.py:223
++#: ../DistUpgrade/DistUpgradeViewKDE.py:371
++#, python-format
++msgid "About %s remaining"
++msgstr "大约还要 %s"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:152
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:155
++#: ../DistUpgrade/DistUpgradeViewKDE.py:225
++#, python-format
++msgid "Fetching file %li of %li"
++msgstr "下载第 %li 个文件(共 %li 个文件)"
++
++#. FIXME: add support for the timeout
++#. of the terminal (to display something useful then)
++#. -> longer term, move this code into python-apt
++#: ../DistUpgrade/DistUpgradeViewGtk.py:183
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:186
++#: ../DistUpgrade/DistUpgradeViewKDE.py:262
++msgid "Applying changes"
++msgstr "正在应用更改"
++
++#. we do not report followup errors from earlier failures
++#: ../DistUpgrade/DistUpgradeViewGtk.py:208
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:212
++#: ../DistUpgrade/DistUpgradeViewKDE.py:275
++msgid "dependency problems - leaving unconfigured"
++msgstr "依赖关系问题 - 保持未配置状态"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:213
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:217
++#: ../DistUpgrade/DistUpgradeViewKDE.py:277
++#, python-format
++msgid "Could not install '%s'"
++msgstr "无法安装“%s”"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:214
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:218
++#: ../DistUpgrade/DistUpgradeViewKDE.py:278
++#, python-format
++msgid ""
++"The upgrade will continue but the '%s' package may not be in a working "
++"state. Please consider submitting a bug report about it."
++msgstr "升级将继续进行,但“%s”可能没有工作。请考虑提交关于它的错误报告。"
++
++#. self.expander.set_expanded(True)
++#: ../DistUpgrade/DistUpgradeViewGtk.py:231
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:235
++#: ../DistUpgrade/DistUpgradeViewKDE.py:299
++#, python-format
++msgid ""
++"Replace the customized configuration file\n"
++"'%s'?"
++msgstr ""
++"替换自定义配置文件\n"
++"“%s”吗?"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:232
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:236
++#: ../DistUpgrade/DistUpgradeViewKDE.py:300
++msgid ""
++"You will lose any changes you have made to this configuration file if you "
++"choose to replace it with a newer version."
++msgstr "如果选择替换为新版本的配置文件,您将会失去所有已做的修改。"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:251
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:256
++#: ../DistUpgrade/DistUpgradeViewKDE.py:323
++msgid "The 'diff' command was not found"
++msgstr "找不到 diff 命令"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:464
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:477
++#: ../DistUpgrade/DistUpgradeViewText.py:92
++msgid "A fatal error occurred"
++msgstr "出现致命错误"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:465
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:478
++msgid ""
++"Please report this as a bug (if you haven't already) and include the files /"
++"var/log/dist-upgrade/main.log and /var/log/dist-upgrade/apt.log in your "
++"report. The upgrade has aborted.\n"
++"Your original sources.list was saved in /etc/apt/sources.list.distUpgrade."
++msgstr ""
++"请报告这个错误(如果还没有的话)并在报告中包括文件 /var/log/dist-upgrade/"
++"main.log 和 /var/log/dist-upgrade/apt.log 。升级已取消。\n"
++"您的原始 sources.list 已保存在 /etc/apt/sources.list.distUpgrade 。"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:482
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:495
++msgid "Ctrl-c pressed"
++msgstr "Crtl+C 被按下"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:483
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:496
++msgid ""
++"This will abort the operation and may leave the system in a broken state. "
++"Are you sure you want to do that?"
++msgstr "这将取消本次操作且可能使系统处于被破坏的状态。您确定要这样做?"
++
++#. append warning
++#: ../DistUpgrade/DistUpgradeViewGtk.py:631
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:629
++msgid "To prevent data loss close all open applications and documents."
++msgstr "为防止数据丢失,请关闭所有打开的应用程序和文档。"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:645
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:643
++#, python-format
++msgid "No longer supported by Canonical (%s)"
++msgstr "不再被 Canonical 支持 (%s)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:646
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:644
++#, python-format
++msgid "<b>Downgrade (%s)</b>"
++msgstr "<b>降级 (%s)</b>"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:647
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:645
++#, python-format
++msgid "Remove (%s)"
++msgstr "卸载 (%s)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:648
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:646
++#, python-format
++msgid "No longer needed (%s)"
++msgstr "不再需要 (%s)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:649
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:647
++#, python-format
++msgid "Install (%s)"
++msgstr "安装 (%s)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:650
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:648
++#, python-format
++msgid "Upgrade (%s)"
++msgstr "升级 (%s)"
++
++#. change = QMessageBox.question(None, _("Media Change"), msg, QMessageBox.Ok, QMessageBox.Cancel)
++#: ../DistUpgrade/DistUpgradeViewKDE.py:196
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:157
++msgid "Media Change"
++msgstr "改变介质"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:335
++msgid "Show Difference >>>"
++msgstr "显示差别 >>>"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:338
++msgid "<<< Hide Difference"
++msgstr "<<< 隐藏差别"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:554
++msgid "Error"
++msgstr "错误"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:568
++msgid "&Cancel"
++msgstr "取消(&C)"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:572
++#: ../DistUpgrade/DistUpgradeViewKDE.py:813
++msgid "&Close"
++msgstr "关闭(&C)"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:618
++msgid "Show Terminal >>>"
++msgstr "显示终端 >>>"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:621
++msgid "<<< Hide Terminal"
++msgstr "<<< 隐藏终端"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:701
++msgid "Information"
++msgstr "信息"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:751
++#: ../DistUpgrade/DistUpgradeViewKDE.py:796
++#: ../DistUpgrade/DistUpgradeViewKDE.py:799 ../DistUpgrade/DistUpgrade.ui.h:7
++msgid "Details"
++msgstr "细节"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:777
++#, python-format
++msgid "No longer supported %s"
++msgstr "不再支持 %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:779
++#, python-format
++msgid "Remove %s"
++msgstr "移除 %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:781
++#: ../DistUpgrade/DistUpgradeViewText.py:182
++#, python-format
++msgid "Remove (was auto installed) %s"
++msgstr "移除(被自动安装的) %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:783
++#, python-format
++msgid "Install %s"
++msgstr "安装 %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:785
++#, python-format
++msgid "Upgrade %s"
++msgstr "升级 %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:809
++#: ../DistUpgrade/DistUpgradeViewText.py:230
++msgid "Restart required"
++msgstr "需要重启"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:809
++msgid "<b><big>Restart the system to complete the upgrade</big></b>"
++msgstr "<b><big>重新启动系统以完成升级</big></b>"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:812 ../DistUpgrade/DistUpgrade.ui.h:14
++#: ../data/gtkbuilder/UpdateManager.ui.h:26
++msgid "_Restart Now"
++msgstr "现在重启(_R)"
++
++#. FIXME make this user friendly
++#: ../DistUpgrade/DistUpgradeViewKDE.py:830
++msgid ""
++"<b><big>Cancel the running upgrade?</big></b>\n"
++"\n"
++"The system could be in an unusable state if you cancel the upgrade. You are "
++"strongly advised to resume the upgrade."
++msgstr ""
++"<b><big>取消正在运行的升级?</big></b>\n"
++"\n"
++"如果取消升级系统可能不稳定,强烈建议您继续升级。"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:834
++msgid "Cancel Upgrade?"
++msgstr "取消升级?"
++
++#: ../DistUpgrade/DistUpgradeView.py:61
++#, python-format
++msgid "%li day"
++msgid_plural "%li days"
++msgstr[0] "%li 天"
++
++#: ../DistUpgrade/DistUpgradeView.py:63
++#, python-format
++msgid "%li hour"
++msgid_plural "%li hours"
++msgstr[0] "%li 小时"
++
++#: ../DistUpgrade/DistUpgradeView.py:65
++#, python-format
++msgid "%li minute"
++msgid_plural "%li minutes"
++msgstr[0] "%li 分钟"
++
++#: ../DistUpgrade/DistUpgradeView.py:66
++#, python-format
++msgid "%li second"
++msgid_plural "%li seconds"
++msgstr[0] "%li 秒"
++
++#. TRANSLATORS: you can alter the ordering of the remaining time
++#. information here if you shuffle %(str_days)s %(str_hours)s %(str_minutes)s
++#. around. Make sure to keep all '$(str_*)s' in the translated string
++#. and do NOT change anything appart from the ordering.
++#.
++#. %(str_hours)s will be either "1 hour" or "2 hours" depending on the
++#. plural form
++#.
++#. Note: most western languages will not need to change this
++#: ../DistUpgrade/DistUpgradeView.py:82
++#, python-format
++msgid "%(str_days)s %(str_hours)s"
++msgstr "%(str_days)s %(str_hours)s"
++
++#. TRANSLATORS: you can alter the ordering of the remaining time
++#. information here if you shuffle %(str_hours)s %(str_minutes)s
++#. around. Make sure to keep all '$(str_*)s' in the translated string
++#. and do NOT change anything appart from the ordering.
++#.
++#. %(str_hours)s will be either "1 hour" or "2 hours" depending on the
++#. plural form
++#.
++#. Note: most western languages will not need to change this
++#: ../DistUpgrade/DistUpgradeView.py:100
++#, python-format
++msgid "%(str_hours)s %(str_minutes)s"
++msgstr "%(str_hours)s %(str_minutes)s"
++
++#. 56 kbit
++#. 1Mbit = 1024 kbit
++#: ../DistUpgrade/DistUpgradeView.py:151
++#, python-format
++msgid ""
++"This download will take about %s with a 1Mbit DSL connection and about %s "
++"with a 56k modem."
++msgstr ""
++"使用 1Mbit 的 DSL 连接下载需要大约 %s 秒的时间, 使用 56K 的调制解调器连接大"
++"约需要 %s 秒时间。"
++
++#. if we have a estimated speed, use it
++#: ../DistUpgrade/DistUpgradeView.py:155
++#, python-format
++msgid "This download will take about %s with your connection. "
++msgstr "根据您的连接速度,这次下载将要用大约 %s 的时间 "
++
++#. Declare these translatable strings from the .ui files here so that
++#. xgettext picks them up.
++#: ../DistUpgrade/DistUpgradeView.py:259 ../DistUpgrade/DistUpgrade.ui.h:21
++msgid "Preparing to upgrade"
++msgstr "正在准备升级"
++
++#: ../DistUpgrade/DistUpgradeView.py:260
++msgid "Getting new software channels"
++msgstr "获得新的软件源"
++
++#: ../DistUpgrade/DistUpgradeView.py:261 ../DistUpgrade/DistUpgrade.ui.h:23
++msgid "Getting new packages"
++msgstr "获取新的软件包"
++
++#: ../DistUpgrade/DistUpgradeView.py:262 ../DistUpgrade/DistUpgrade.ui.h:26
++msgid "Installing the upgrades"
++msgstr "正在安装升级"
++
++#: ../DistUpgrade/DistUpgradeView.py:263 ../DistUpgrade/DistUpgrade.ui.h:25
++msgid "Cleaning up"
++msgstr "正在清理"
++
++#: ../DistUpgrade/DistUpgradeView.py:348
++#, python-format
++msgid ""
++"%(amount)d installed package is no longer supported by Canonical. You can "
++"still get support from the community."
++msgid_plural ""
++"%(amount)d installed packages are no longer supported by Canonical. You can "
++"still get support from the community."
++msgstr[0] ""
++"%(amount)d 个已安装的软件包不再被 Canonical 支持。您仍然可以获得社区支持。"
++
++#. FIXME: make those two separate lines to make it clear
++#. that the "%" applies to the result of ngettext
++#: ../DistUpgrade/DistUpgradeView.py:357
++#, python-format
++msgid "%d package is going to be removed."
++msgid_plural "%d packages are going to be removed."
++msgstr[0] "将删除 %d 个软件包。"
++
++#: ../DistUpgrade/DistUpgradeView.py:362
++#, python-format
++msgid "%d new package is going to be installed."
++msgid_plural "%d new packages are going to be installed."
++msgstr[0] "将安装 %d 个新的软件包。"
++
++#: ../DistUpgrade/DistUpgradeView.py:368
++#, python-format
++msgid "%d package is going to be upgraded."
++msgid_plural "%d packages are going to be upgraded."
++msgstr[0] "将升级 %d 个软件包。"
++
++#: ../DistUpgrade/DistUpgradeView.py:373
++#, python-format
++msgid ""
++"\n"
++"\n"
++"You have to download a total of %s. "
++msgstr ""
++"\n"
++"\n"
++"您共需下载 %s。 "
++
++#: ../DistUpgrade/DistUpgradeView.py:378
++msgid ""
++"Installing the upgrade can take several hours. Once the download has "
++"finished, the process cannot be canceled."
++msgstr "安装升级可能会耗费几小时的时间。一旦下载完毕就不能取消该进程。"
++
++#: ../DistUpgrade/DistUpgradeView.py:382
++msgid ""
++"Fetching and installing the upgrade can take several hours. Once the "
++"download has finished, the process cannot be canceled."
++msgstr ""
++"升级文件的获取和安装可能会耗费几小时的时间。一旦下载完毕就不能取消该进程。"
++
++#: ../DistUpgrade/DistUpgradeView.py:387
++msgid "Removing the packages can take several hours. "
++msgstr "包的删除可能会耗费几小时的时间。 "
++
++#. FIXME: this should go into DistUpgradeController
++#: ../DistUpgrade/DistUpgradeView.py:392 ../UpdateManager/UpdateManager.py:676
++msgid "The software on this computer is up to date."
++msgstr "此计算机软件是最新的"
++
++#: ../DistUpgrade/DistUpgradeView.py:393
++msgid ""
++"There are no upgrades available for your system. The upgrade will now be "
++"canceled."
++msgstr "你的系统没有可用升级。升级被取消。"
++
++#: ../DistUpgrade/DistUpgradeView.py:406
++msgid "Reboot required"
++msgstr "需要重启"
++
++#: ../DistUpgrade/DistUpgradeView.py:407
++msgid ""
++"The upgrade is finished and a reboot is required. Do you want to do this now?"
++msgstr "升级已经完成并需要重启。您要现在重启么?"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:72
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:72
++#, python-format
++msgid "authenticate '%(file)s' against '%(signature)s' "
++msgstr "使用 '%(signature)s' 对 '%(file)s' 进行验证 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:131
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:131
++#, python-format
++msgid "extracting '%s'"
++msgstr "正在提取 '%s'"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:151
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:152
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:151
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:152
++msgid "Could not run the upgrade tool"
++msgstr "不能运行升级工具"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:152
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:152
++msgid ""
++"This is most likely a bug in the upgrade tool. Please report it as a bug "
++"using the command 'ubuntu-bug update-manager'."
++msgstr ""
++"这可能是升级工具的一个 bug,请使用命令‘ubuntu-bug update-manager’来报告这个 "
++"bug。"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:227
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:227
++msgid "Upgrade tool signature"
++msgstr "升级工具签名"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:234
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:234
++msgid "Upgrade tool"
++msgstr "升级工具"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:268
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:268
++msgid "Failed to fetch"
++msgstr "下载失败"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:269
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:269
++msgid "Fetching the upgrade failed. There may be a network problem. "
++msgstr "获取升级信息失败。可能网络有问题。 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:273
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:273
++msgid "Authentication failed"
++msgstr "认证失败"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:274
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:274
++msgid ""
++"Authenticating the upgrade failed. There may be a problem with the network "
++"or with the server. "
++msgstr "认证升级信息失败。可能是网络或服务器的问题。 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:279
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:279
++msgid "Failed to extract"
++msgstr "提取失败"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:280
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:280
++msgid ""
++"Extracting the upgrade failed. There may be a problem with the network or "
++"with the server. "
++msgstr "提取升级信息失败。可能是网络或服务器的问题。 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:285
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:285
++msgid "Verification failed"
++msgstr "验证失败"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:286
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:286
++msgid ""
++"Verifying the upgrade failed.  There may be a problem with the network or "
++"with the server. "
++msgstr "验证升级程序失败。可能是网络或服务器的问题。 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:300
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:306
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:300
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:306
++msgid "Can not run the upgrade"
++msgstr "不能运行升级"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:301
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:301
++msgid ""
++"This usually is caused by a system where /tmp is mounted noexec. Please "
++"remount without noexec and run the upgrade again."
++msgstr ""
++"可能的原因是系统的 /tmp 目录无可执行权限。请以可执行权限重新挂载该目录,重新"
++"升级。"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:307
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:307
++#, python-format
++msgid "The error message is '%s'."
++msgstr "错误信息是“%s”。"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:93
++msgid ""
++"Please report this as a bug and include the files /var/log/dist-upgrade/main."
++"log and /var/log/dist-upgrade/apt.log in your report. The upgrade has "
++"aborted.\n"
++"Your original sources.list was saved in /etc/apt/sources.list.distUpgrade."
++msgstr ""
++"请报告这个错误并在报告中包括文件 /var/log/dist-upgrade/main.log 和 /var/log/"
++"dist-upgrade/apt.log 。升级已取消。\n"
++"您的原始 sources.list 已保存在 /etc/apt/sources.list.distUpgrade 。"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:117
++msgid "Aborting"
++msgstr "中止"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:122
++msgid "Demoted:\n"
++msgstr "降级:\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:129
++msgid "To continue please press [ENTER]"
++msgstr "按 [ENTER] 键以继续"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:157
++#: ../DistUpgrade/DistUpgradeViewText.py:196
++#: ../DistUpgrade/DistUpgradeViewText.py:203
++msgid "Continue [yN] "
++msgstr "继续 [yN] "
++
++#: ../DistUpgrade/DistUpgradeViewText.py:157
++#: ../DistUpgrade/DistUpgradeViewText.py:196
++msgid "Details [d]"
++msgstr "详细信息[d]"
++
++#. TRANSLATORS: the "y" is "yes"
++#. TRANSLATORS: first letter of a positive (yes) answer
++#: ../DistUpgrade/DistUpgradeViewText.py:162
++#: ../DistUpgrade/DistUpgradeViewText.py:206
++msgid "y"
++msgstr "y"
++
++#. TRANSLATORS: the "n" is "no"
++#. TRANSLATORS: first letter of a negative (no) answer
++#: ../DistUpgrade/DistUpgradeViewText.py:165
++#: ../DistUpgrade/DistUpgradeViewText.py:213
++msgid "n"
++msgstr "n"
++
++#. TRANSLATORS: the "d" is "details"
++#: ../DistUpgrade/DistUpgradeViewText.py:168
++msgid "d"
++msgstr "详"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:173
++#, python-format
++msgid "No longer supported: %s\n"
++msgstr "不再支持:%s\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:178
++#, python-format
++msgid "Remove: %s\n"
++msgstr "移除:%s\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:188
++#, python-format
++msgid "Install: %s\n"
++msgstr "安装:%s\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:193
++#, python-format
++msgid "Upgrade: %s\n"
++msgstr "升级:%s\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:210
++msgid "Continue [Yn] "
++msgstr "继续 [Yn] "
++
++#: ../DistUpgrade/DistUpgradeViewText.py:231
++msgid ""
++"To finish the upgrade, a restart is required.\n"
++"If you select 'y' the system will be restarted."
++msgstr ""
++"为了完成升级,必须重新启动。\n"
++"如果你选择“是”,系统将会重新启动。"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:1
++msgid "_Cancel Upgrade"
++msgstr "取消升级"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:2
++msgid "_Resume Upgrade"
++msgstr "恢复升级(_R)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:3
++msgid ""
++"<b><big>Cancel the running upgrade?</big></b>\n"
++"\n"
++"The system could be in an unusable state if you cancel the upgrade. You are "
++"strongly adviced to resume the upgrade."
++msgstr ""
++"<b><big>取消正在运行的升级?</big></b>\n"
++"如果您取消升级,系统可能不稳定。强烈建议您继续升级。"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:6
++msgid "_Start Upgrade"
++msgstr "开始升级(_R)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:9
++msgid "_Replace"
++msgstr "替换(_R)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:10
++msgid "Difference between the files"
++msgstr "文件之间的差别"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:11
++msgid "_Report Bug"
++msgstr "报告 Bug(_R)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:12
++msgid "_Continue"
++msgstr "继续(_C)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:13
++msgid "<b><big>Start the upgrade?</big></b>"
++msgstr "<b><big>开始升级?</big></b>"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:15
++msgid ""
++"<b><big>Restart the system to complete the upgrade</big></b>\n"
++"\n"
++"Please save your work before continuing."
++msgstr ""
++"<b><big>重启系统以完成升级</big></b>\n"
++"\n"
++"请在继续前保存你的工作。"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:18
++msgid "Distribution Upgrade"
++msgstr "发行版升级"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:19
++#, fuzzy
++msgid "<b><big>Upgrading Ubuntu to version 12.10</big></b>"
++msgstr "<b><big>把 Ubuntu 升级到 11.10</big></b>"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:20
++msgid "    "
++msgstr "    "
++
++#: ../DistUpgrade/DistUpgrade.ui.h:22
++msgid "Setting new software channels"
++msgstr "设定新的软件源"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:24
++msgid "Restarting the computer"
++msgstr "系统正在重新启动"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:27
++msgid "Terminal"
++msgstr "终端"
++
++#: ../UpdateManager/backend/InstallBackendSynaptic.py:64
++msgid "Please wait, this can take some time."
++msgstr "请稍候,这需要花一些时间。"
++
++#: ../UpdateManager/backend/InstallBackendSynaptic.py:66
++msgid "Update is complete"
++msgstr "更新完成"
++
++#: ../UpdateManager/DistUpgradeFetcher.py:114
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:109
++msgid "Could not find the release notes"
++msgstr "无法找到发行注记"
++
++#: ../UpdateManager/DistUpgradeFetcher.py:115
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:110
++msgid "The server may be overloaded. "
++msgstr "服务器可能已过载。 "
++
++#: ../UpdateManager/DistUpgradeFetcher.py:125
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:114
++msgid "Could not download the release notes"
++msgstr "无法下载发行说明"
++
++#: ../UpdateManager/DistUpgradeFetcher.py:126
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:115
++msgid "Please check your internet connection."
++msgstr "请检查您的互联网连接。"
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:68
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:91
++msgid "Upgrade"
++msgstr "升级"
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:95
++#: ../data/gtkbuilder/UpdateManager.ui.h:20
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:2
++msgid "Release Notes"
++msgstr "发行注记"
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:134
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:148
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:150
++msgid "Downloading additional package files..."
++msgstr "正在下载附加软件包..."
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:148
++#, python-format
++msgid "File %s of %s at %sB/s"
++msgstr "文件 %s/%s 速度: %sB/s"
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:150
++#, python-format
++msgid "File %s of %s"
++msgstr "文件 %s/%s"
++
++#: ../UpdateManager/ChangelogViewer.py:75
++msgid "Open Link in Browser"
++msgstr "在浏览器中打开链接"
++
++#: ../UpdateManager/ChangelogViewer.py:78
++msgid "Copy Link to Clipboard"
++msgstr "复制链接到剪贴板"
++
++#: ../UpdateManager/GtkProgress.py:162
++#, python-format
++msgid "Downloading file %(current)li of %(total)li with %(speed)s/s"
++msgstr "正在下载文件 %(current)li/%(total)li 速度 %(speed)s/s"
++
++#: ../UpdateManager/GtkProgress.py:167
++#, python-format
++msgid "Downloading file %(current)li of %(total)li"
++msgstr "正在下载文件 %(current)li/%(total)li"
++
++#: ../UpdateManager/UpdateManager.py:106 ../do-release-upgrade:100
++msgid "Your Ubuntu release is not supported anymore."
++msgstr "不再提供您的 Ubuntu 版本的支持。"
++
++#: ../UpdateManager/UpdateManager.py:107
++msgid ""
++"You will not get any further security fixes or critical updates. Please "
++"upgrade to a later version of Ubuntu."
++msgstr "不会得到进一步的安全修补程序或关键更新。请升级到较新的 Ubuntu 版本。"
++
++#: ../UpdateManager/UpdateManager.py:115
++msgid "Upgrade information"
++msgstr "升级信息"
++
++#: ../UpdateManager/UpdateManager.py:233
++#: ../UpdateManagerText/UpdateManagerText.py:35
++msgid "Install"
++msgstr "安装"
++
++#: ../UpdateManager/UpdateManager.py:235
++msgid "Name"
++msgstr "名称"
++
++#. upload_archive = version_match.group(2).strip()
++#: ../UpdateManager/UpdateManager.py:395
++#, python-format
++msgid "Version %s: \n"
++msgstr "版本 %s: \n"
++
++#: ../UpdateManager/UpdateManager.py:453
++msgid ""
++"No network connection detected, you can not download changelog information."
++msgstr "未检测到网络连接,您无法下载更新日志。"
++
++#: ../UpdateManager/UpdateManager.py:463
++msgid "Downloading list of changes..."
++msgstr "正在下载更新列表..."
++
++#: ../UpdateManager/UpdateManager.py:507
++msgid "_Deselect All"
++msgstr "全部不选(_D)"
++
++#: ../UpdateManager/UpdateManager.py:513
++msgid "Select _All"
++msgstr "选择全部(_A)"
++
++#: ../UpdateManager/UpdateManager.py:572
++#, python-format
++msgid "%s will be downloaded."
++msgstr "将会下载 %s。"
++
++#: ../UpdateManager/UpdateManager.py:584
++#, fuzzy
++msgid "The update has already been downloaded."
++msgid_plural "The updates have already been downloaded."
++msgstr[0] "该更新已下载完毕但未安装。"
++
++#: ../UpdateManager/UpdateManager.py:589
++msgid "There are no updates to install."
++msgstr ""
++
++#: ../UpdateManager/UpdateManager.py:598
++msgid "Unknown download size."
++msgstr "未知下载大小。"
++
++#: ../UpdateManager/UpdateManager.py:624
++msgid ""
++"It is unknown when the package information was updated last. Please click "
++"the 'Check' button to update the information."
++msgstr "软件包信息上次更新的时间未知。请点击“检查”按钮更新软件包信息。"
++
++#: ../UpdateManager/UpdateManager.py:630
++#, python-format
++msgid ""
++"The package information was last updated %(days_ago)s days ago.\n"
++"Press the 'Check' button below to check for new software updates."
++msgstr ""
++"%(days_ago)s 天前最后一次更新软件包信息。\n"
++"要检查软件更新,点击下面的“检查”按钮。"
++
++#: ../UpdateManager/UpdateManager.py:635
++#, python-format
++msgid "The package information was last updated %(days_ago)s day ago."
++msgid_plural "The package information was last updated %(days_ago)s days ago."
++msgstr[0] "软件包信息上次是在 %(days_ago)s 天前更新的。"
++
++#: ../UpdateManager/UpdateManager.py:639
++#, python-format
++msgid "The package information was last updated %(hours_ago)s hour ago."
++msgid_plural ""
++"The package information was last updated %(hours_ago)s hours ago."
++msgstr[0] "软件包信息上次是在 %(hours_ago)s 小时前更新的。"
++
++#. TRANSLATORS: only in plural form, as %s minutes ago is one of 15, 30, 45 minutes ago
++#: ../UpdateManager/UpdateManager.py:644 ../UpdateManager/UpdateManager.py:646
++#: ../UpdateManager/UpdateManager.py:648
++#, python-format
++msgid "The package information was last updated about %s minutes ago."
++msgstr "该软件包信息已在 %s 分钟之前更新。"
++
++#: ../UpdateManager/UpdateManager.py:650
++msgid "The package information was just updated."
++msgstr "该软件包信息刚刚更新。"
++
++#: ../UpdateManager/UpdateManager.py:689
++msgid "Software updates may be available for your computer."
++msgstr "您的计算机有可用的软件更新。"
++
++#: ../UpdateManager/UpdateManager.py:697
++#, python-format
++msgid ""
++"Updated software has been issued since %s was released. Do you want to "
++"install it now?"
++msgstr ""
++
++#: ../UpdateManager/UpdateManager.py:700
++msgid ""
++"Updated software is available for this computer. Do you want to install it "
++"now?"
++msgstr ""
++
++#: ../UpdateManager/UpdateManager.py:758
++#, python-format
++msgid ""
++"The upgrade needs a total of %s free space on disk '%s'. Please free at "
++"least an additional %s of disk space on '%s'. Empty your trash and remove "
++"temporary packages of former installations using 'sudo apt-get clean'."
++msgstr ""
++"这个更新需要花去 %s 磁盘上总计 %s 的空间。请在 %s 磁盘上留出 %s 空间。清空您"
++"的回收站和临时文件,用“sudo apt-get clean”清理以前的安装文件。"
++
++#: ../UpdateManager/UpdateManager.py:783
++msgid ""
++"The computer needs to restart to finish installing updates. Please save your "
++"work before continuing."
++msgstr "计算机需要重新启动来完成更新。请在继续操作前保存好您的工作。"
++
++#: ../UpdateManager/UpdateManager.py:847
++msgid "Reading package information"
++msgstr "读取软件包信息"
++
++#: ../UpdateManager/UpdateManager.py:862
++msgid "Connecting..."
++msgstr "正在连接..."
++
++#: ../UpdateManager/UpdateManager.py:879
++msgid "You may not be able to check for updates or download new updates."
++msgstr "您可能无法检查更新或下载新的更新。"
++
++#: ../UpdateManager/UpdateManager.py:1002
++msgid "Could not initialize the package information"
++msgstr "无法初始化软件包信息"
++
++msgid "An unresolvable problem occurred while initializing the package."
++msgstr "初始化包信息时遇到无法解决的问题。"
++
++#: ../UpdateManager/UpdateManager.py:1003
++msgid ""
++"An unresolvable problem occurred while initializing the package "
++"information.\n"
++"\n"
++"Please report this bug against the 'kylin-system-updater' package and include the "
++"following error message:\n"
++msgstr ""
++"初始化包信息时遇到无法解决的问题。\n"
++"\n"
++"请汇报这个“kylin-system-updater”软件包的错误,并且将如下信息包含在报告中:\n"
++
++#: ../UpdateManager/UpdateManager.py:1032
++msgid ""
++"An unresolvable problem occurred while calculating the upgrade.\n"
++"\n"
++"Please report this bug against the 'kylin-system-updater' package and include the "
++"following error message:"
++msgstr ""
++"在计算升级时遇到一个无法解决的问题。\n"
++"\n"
++"请汇报这个有关“update-manager”软件包的错误,并且将下列错误信息包含在错误报告"
++"中:"
++
++#: ../UpdateManager/UpdateManager.py:1056
++msgid " (New install)"
++msgstr " (新安装)"
++
++#. TRANSLATORS: the b stands for Bytes
++#: ../UpdateManager/UpdateManager.py:1063
++#, python-format
++msgid "(Size: %s)"
++msgstr "(大小:%s)"
++
++#: ../UpdateManager/UpdateManager.py:1067
++#, python-format
++msgid "From version %(old_version)s to %(new_version)s"
++msgstr "从版本 %(old_version)s 到 %(new_version)s"
++
++#: ../UpdateManager/UpdateManager.py:1071
++#, python-format
++msgid "Version %s"
++msgstr "版本 %s"
++
++#: ../UpdateManager/UpdateManager.py:1104 ../do-release-upgrade:112
++msgid "Release upgrade not possible right now"
++msgstr "版本升级目前不可用"
++
++#: ../UpdateManager/UpdateManager.py:1105 ../do-release-upgrade:113
++#, c-format, python-format
++msgid ""
++"The release upgrade can not be performed currently, please try again later. "
++"The server reported: '%s'"
++msgstr "发行版目前无法更新,请再试一次。服务器报告:'%s'"
++
++#: ../UpdateManager/UpdateManager.py:1107 ../check-new-release-gtk:126
++msgid "Downloading the release upgrade tool"
++msgstr "正在下载发布升级工具"
++
++#: ../UpdateManager/UpdateManager.py:1114
++#, python-format
++msgid "<b>New Ubuntu release '%s' is available</b>"
++msgstr "<b>新的 Ubuntu 发行版 %s 可用</b>"
++
++#. we assert a clean cache
++#: ../UpdateManager/UpdateManager.py:1153
++msgid "Software index is broken"
++msgstr "软件索引已经损坏"
++
++#: ../UpdateManager/UpdateManager.py:1154
++msgid ""
++"It is impossible to install or remove any software. Please use the package "
++"manager \"Synaptic\" or run \"sudo apt-get install -f\" in a terminal to fix "
++"this issue at first."
++msgstr ""
++"无法安装或删除任何软件。请在终端运行 \"sudo apt-get "
++"install -f\" 来修正这个问题。"
++
++#: ../UpdateManager/UnitySupport.py:57
++msgid "Check for Updates"
++msgstr "检查更新"
++
++#: ../UpdateManager/UnitySupport.py:66
++msgid "Install All Available Updates"
++msgstr "安装全部可利用的更新"
++
++#: ../UpdateManagerText/UpdateManagerText.py:34
++msgid "Cancel"
++msgstr "取消"
++
++#: ../UpdateManagerText/UpdateManagerText.py:37
++msgid "Changelog"
++msgstr "变更日志"
++
++#: ../UpdateManagerText/UpdateManagerText.py:40
++msgid "Updates"
++msgstr "更新"
++
++#: ../UpdateManagerText/UpdateManagerText.py:53
++msgid "Building Updates List"
++msgstr "正在建立更新列表"
++
++#: ../UpdateManagerText/UpdateManagerText.py:56
++msgid ""
++"\n"
++"A normal upgrade can not be calculated, please run: \n"
++"  sudo apt-get dist-upgrade\n"
++"\n"
++"\n"
++"This can be caused by:\n"
++" * A previous upgrade which didn't complete\n"
++" * Problems with some of the installed software\n"
++" * Unofficial software packages not provided by Ubuntu\n"
++" * Normal changes of a pre-release version of Ubuntu"
++msgstr ""
++"\n"
++"一个普通升级无法被计算,请运行: \n"
++"  sudo apt-get dist-upgrade\n"
++"\n"
++"\n"
++"这可能是因为:\n"
++" * 先前的升级尚未完成\n"
++" * 已安装软件引起的问题\n"
++" * 不是由 Ubuntu 提供的非官方软件包\n"
++" * Ubuntu 预发行版本的普通更改"
++
++#: ../UpdateManagerText/UpdateManagerText.py:125
++msgid "Downloading changelog"
++msgstr "正在下载变更日志"
++
++#: ../UpdateManager/Core/MyCache.py:147
++#, python-format
++msgid "Other updates (%s)"
++msgstr "其它更新 (%s)"
++
++#: ../UpdateManager/Core/MyCache.py:325
++msgid "This update does not come from a source that supports changelogs."
++msgstr ""
++
++#: ../UpdateManager/Core/MyCache.py:331 ../UpdateManager/Core/MyCache.py:359
++msgid ""
++"Failed to download the list of changes. \n"
++"Please check your Internet connection."
++msgstr ""
++
++#: ../UpdateManager/Core/MyCache.py:338
++#, python-format
++msgid ""
++"Changes for the versions:\n"
++"Installed version: %s\n"
++"Available version: %s\n"
++"\n"
++msgstr ""
++"版本变更:\n"
++"已安装的版本:%s\n"
++"可用版本:%s\n"
++"\n"
++
++#: ../UpdateManager/Core/MyCache.py:348
++#, python-format
++msgid ""
++"The changelog does not contain any relevant changes.\n"
++"\n"
++"Please use http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n"
++"until the changes become available or try again later."
++msgstr ""
++
++#: ../UpdateManager/Core/MyCache.py:353
++#, python-format
++msgid ""
++"The list of changes is not available yet.\n"
++"\n"
++"Please use http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n"
++"until the changes become available or try again later."
++msgstr ""
++
++#: ../UpdateManager/Core/UpdateList.py:51
++msgid "Failed to detect distribution"
++msgstr "检测发行版失败"
++
++#: ../UpdateManager/Core/UpdateList.py:52
++#, python-format
++msgid "A error '%s' occurred while checking what system you are using."
++msgstr "检查您正在使用哪种系统的时候发生一个错误 “%s”。"
++
++#: ../UpdateManager/Core/UpdateList.py:63
++msgid "Important security updates"
++msgstr "重要安全更新"
++
++#: ../UpdateManager/Core/UpdateList.py:64
++msgid "Recommended updates"
++msgstr "推荐更新"
++
++#: ../UpdateManager/Core/UpdateList.py:65
++msgid "Proposed updates"
++msgstr "提前释放的更新"
++
++#: ../UpdateManager/Core/UpdateList.py:66
++msgid "Backports"
++msgstr "Backports"
++
++#: ../UpdateManager/Core/UpdateList.py:67
++msgid "Distribution updates"
++msgstr "发行版升级"
++
++#: ../UpdateManager/Core/UpdateList.py:72
++msgid "Other updates"
++msgstr "其它更新"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:1
++#, fuzzy
++msgid "<big><b>Starting Software Updater</b></big>"
++msgstr "<b><big>运行升级管理器</big></b>"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:2
++msgid ""
++"Software updates correct errors, eliminate security vulnerabilities and "
++"provide new features."
++msgstr "软件更新可以为您修复错误,消除安全漏洞及提供新的特性"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:3
++msgid "_Partial Upgrade"
++msgstr "部分升级(_P)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:4
++msgid "<big><b>Not all updates can be installed</b></big>"
++msgstr "<big><b>没有更新可供安装</b></big>"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:5
++msgid ""
++"Run a partial upgrade, to install as many updates as possible. \n"
++"\n"
++"This can be caused by:\n"
++" * A previous upgrade which didn't complete\n"
++" * Problems with some of the installed software\n"
++" * Unofficial software packages not provided by Ubuntu\n"
++" * Normal changes of a pre-release version of Ubuntu"
++msgstr ""
++"执行一次部分升级,安装尽可能多的更新。 \n"
++"\n"
++"这可能是下面的情况引起的:\n"
++" * 前一次升级没有完成\n"
++" * 一些已经安装的软件的问题\n"
++" *Ubuntu 不支持的非官方软件包\n"
++" *Ubuntu 预发布版本的正常变动"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:12
++msgid "Chec_k"
++msgstr "检查(_K)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:13
++msgid ""
++"<b><big>You must check for updates manually</big></b>\n"
++"\n"
++"Your system does not check for updates automatically. You can configure this "
++"behavior in <i>Software Sources</i> on the <i>Updates</i> tab."
++msgstr ""
++"<b><big>您必须手动检测升级</big></b>\n"
++"\n"
++"您的系统未自动检测升级,可以通过编辑<i>软件源</i>在<i>网络升级</i>中更改。"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:16
++msgid "_Hide this information in the future"
++msgstr "不再显示该信息(_H)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:17
++msgid "Co_ntinue"
++msgstr "继续(_N)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:18
++msgid "<big><b>Running on battery</b></big>"
++msgstr "<big><b>电池供电</b></big>"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:19
++msgid "Your system is running on battery. Are you sure you want to continue?"
++msgstr "您的系统正在使用电池。 您确定要继续吗?"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:21
++msgid "_Upgrade"
++msgstr "升级(_U)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:22
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:8
++msgid "Show progress of individual files"
++msgstr "显示单个文件进度"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:23
++#: ../data/update-manager.desktop.in.h:1
++#, fuzzy
++msgid "Software Updater"
++msgstr "软件更新"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:24
++#, fuzzy
++msgid "Starting Software Updater"
++msgstr "软件更新"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:25
++msgid "U_pgrade"
++msgstr "升级(_P)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:27
++msgid "updates"
++msgstr "更新"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:28
++msgid "Changes"
++msgstr "变更"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:29
++msgid "Description"
++msgstr "描述"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:30
++#, fuzzy
++msgid "Details of updates"
++msgstr "升级描述"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:31
++msgid ""
++"You are connected via roaming and may be charged for the data consumed by "
++"this update."
++msgstr "您正在使用漫游连接,更新可能会耗费很多流量。"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:32
++msgid ""
++"You may want to wait until you’re not using a mobile broadband connection."
++msgstr ""
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:33
++msgid "It’s safer to connect the computer to AC power before updating."
++msgstr "在更新前最好将计算机连接电源。"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:34
++msgid "_Settings..."
++msgstr "设置(_S)..."
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:35
++#, fuzzy
++msgid "_Install Now"
++msgstr "安装"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:1
++msgid "<b>A new version of Ubuntu is available. Would you like to upgrade?</b>"
++msgstr "<b>有新版本的 Ubuntu 可用。您想升级吗?</b>"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:3
++msgid "Don't Upgrade"
++msgstr "不升级"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:4
++msgid "Ask Me Later"
++msgstr "稍后询问"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:5
++msgid "Yes, Upgrade Now"
++msgstr "是的,现在就升级"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:6
++msgid "You have declined to upgrade to the new Ubuntu"
++msgstr "您已经拒绝升级到新版本的 Ubuntu"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:7
++#, fuzzy
++msgid ""
++"You can upgrade at a later time by opening Software Updater and click on "
++"\"Upgrade\"."
++msgstr "如果您希望以后再升级,可以打开更新管理器,然后点击“升级”。"
++
++#: ../data/update-manager.desktop.in.h:2
++msgid "Software Updates"
++msgstr "软件更新"
++
++#: ../data/update-manager.desktop.in.h:3
++msgid "Show and install available updates"
++msgstr "显示并安装可用更新"
++
++#: ../update-manager:66 ../update-manager-text:55 ../do-release-upgrade:51
++msgid "Show version and exit"
++msgstr "显示版本并退出"
++
++#: ../update-manager:69
++msgid "Directory that contains the data files"
++msgstr "包含数据文件的文件夹"
++
++#: ../update-manager:72
++msgid "Check if a new Ubuntu release is available"
++msgstr "检查是否有新的 Ubuntu 发行版可用"
++
++#: ../update-manager:75 ../do-release-upgrade:54 ../check-new-release-gtk:186
++msgid "Check if upgrading to the latest devel release is possible"
++msgstr "验证是否能够升级到最新版本"
++
++#: ../update-manager:79
++msgid "Upgrade using the latest proposed version of the release upgrader"
++msgstr "使用最新 proposed 版本的升级器升级"
++
++#: ../update-manager:86
++msgid "Do not focus on map when starting"
++msgstr "开始时焦点不要定位在图上"
++
++#: ../update-manager:89
++msgid "Try to run a dist-upgrade"
++msgstr "尝试进行版本升级"
++
++#: ../update-manager:92
++msgid "Do not check for updates when starting"
++msgstr "启动时不检查更新"
++
++#: ../update-manager:96 ../do-release-upgrade:70
++msgid "Test upgrade with a sandbox aufs overlay"
++msgstr "进行带沙盒 aufs 隔离层的测试升级"
++
++#: ../update-manager:116
++msgid "Running partial upgrade"
++msgstr "运行部分升级"
++
++msgid " Will be deleted Due to Upgrade "
++msgstr " 将要被删除,由于升级 "
++
++msgid " Will be deleted Due to Install or Upgrade "
++msgstr " 将要被删除,由于安装 "
++
++#: ../update-manager-text:59
++msgid "Show description of the package instead of the changelog"
++msgstr "显示包的说明而不是变更日志"
++
++#: ../do-release-upgrade:58 ../check-new-release-gtk:190
++msgid ""
++"Try upgrading to the latest release using the upgrader from $distro-proposed"
++msgstr "尝试通过 $distro-proposed 更新到最新版本。"
++
++#: ../do-release-upgrade:62
++msgid ""
++"Run in a special upgrade mode.\n"
++"Currently 'desktop' for regular upgrades of a desktop system and 'server' "
++"for server systems are supported."
++msgstr ""
++"以特定模式升级。\n"
++"目前支持:用“桌面”为桌面系统,“服务器”为服务器系统升级。"
++
++#: ../do-release-upgrade:68
++msgid "Run the specified frontend"
++msgstr "运行指定的前端"
++
++#: ../do-release-upgrade:73
++msgid ""
++"Check only if a new distribution release is available and report the result "
++"via the exit code"
++msgstr "仅在有新的发行版发布时检查,并通过退出码(exit code)报告结果"
++
++#: ../do-release-upgrade:87
++msgid "Checking for a new Ubuntu release"
++msgstr "正在检查新版 Ubuntu"
++
++#: ../do-release-upgrade:101
++msgid ""
++"For upgrade information, please visit:\n"
++"%(url)s\n"
++msgstr ""
++"要获得关于升级的信息,请访问:\n"
++"%(url)s\n"
++
++#: ../do-release-upgrade:107
++msgid "No new release found"
++msgstr "未发现新版本"
++
++#: ../do-release-upgrade:119
++#, c-format
++msgid "New release '%s' available."
++msgstr "有新版本“%s”可供使用"
++
++#: ../do-release-upgrade:120
++msgid "Run 'do-release-upgrade' to upgrade to it."
++msgstr "运行“do-release-upgrade”来升级到新版本。"
++
++#: ../check-new-release-gtk:101
++msgid "Ubuntu %(version)s Upgrade Available"
++msgstr "Ubuntu %(version)s 升级可用"
++
++#: ../check-new-release-gtk:143
++#, c-format
++msgid "You have declined the upgrade to Ubuntu %s"
++msgstr "您已经拒绝升级到 Ubuntu %s"
++
++#: ../check-new-release-gtk:196
++msgid "Add debug output"
++msgstr "添加调试输出"
++
++#: ../ubuntu-support-status:91
++msgid "Show unsupported packages on this machine"
++msgstr "显示此计算机中不受支持的包"
++
++#: ../ubuntu-support-status:94
++msgid "Show supported packages on this machine"
++msgstr "显示此计算机中受支持的包"
++
++#: ../ubuntu-support-status:97
++msgid "Show all packages with their status"
++msgstr "显示所有包及其状态"
++
++#: ../ubuntu-support-status:100
++msgid "Show all packages in a list"
++msgstr "列出所有包"
++
++#: ../ubuntu-support-status:142
++#, c-format
++msgid "Support status summary of '%s':"
++msgstr "'%s' 的支持状态摘要:"
++
++#: ../ubuntu-support-status:145
++msgid "You have %(num)s packages (%(percent).1f%%) supported until %(time)s"
++msgstr "有 %(num)s 个包(%(percent).1f%%)的支持截止时间是 %(time)s"
++
++#: ../ubuntu-support-status:151
++msgid ""
++"You have %(num)s packages (%(percent).1f%%) that can not/no-longer be "
++"downloaded"
++msgstr "有 %(num)s 个包(%(percent).1f%%) (已)不能不能下载"
++
++#: ../ubuntu-support-status:154
++msgid "You have %(num)s packages (%(percent).1f%%) that are unsupported"
++msgstr "有 %(num)s 个包(%(percent).1f%%)不受支持"
++
++#: ../ubuntu-support-status:162
++msgid ""
++"Run with --show-unsupported, --show-supported or --show-all to see more "
++"details"
++msgstr ""
++"通过 --show-unsupported、--show-supported 或 --show-all 运行以查看更多详细信"
++"息"
++
++#: ../ubuntu-support-status:166
++msgid "No longer downloadable:"
++msgstr "已不能下载:"
++
++#: ../ubuntu-support-status:169
++msgid "Unsupported: "
++msgstr "不受支持: "
++
++#: ../ubuntu-support-status:174
++#, c-format
++msgid "Supported until %s:"
++msgstr "支持截止时间 %s:"
++
++#: ../ubuntu-support-status:183
++msgid "Unsupported"
++msgstr "不受支持"
++
++#. Why do we use %s here instead of $strings or {} format placeholders?
++#. It's because we don't want to break existing translations.
++#: ../janitor/plugincore/exceptions.py:42
++#, python-format
++msgid "Unimplemented method: %s"
++msgstr "尚未实现的方法:%s"
++
++#: ../janitor/plugincore/core/file_cruft.py:41
++msgid "A file on disk"
++msgstr "磁盘上的文件"
++
++#: ../janitor/plugincore/core/missing_package_cruft.py:39
++msgid "Install missing package."
++msgstr "安装缺失的软件包。"
++
++#. 2012-06-08 BAW: i18n string; don't use {} or PEP 292.
++#: ../janitor/plugincore/core/missing_package_cruft.py:49
++#, python-format
++msgid "Package %s should be installed."
++msgstr "包 %s 应当被安装。"
++
++#: ../janitor/plugincore/core/package_cruft.py:49
++msgid ".deb package"
++msgstr ".deb 软件包"
++
++#: ../janitor/plugincore/plugins/langpack_manual_plugin.py:46
++#, python-format
++msgid "%s needs to be marked as manually installed."
++msgstr "%s 需要标记为手动安装。"
++
++#: ../janitor/plugincore/plugins/kdelibs4to5_plugin.py:49
++msgid ""
++"When upgrading, if kdelibs4-dev is installed, kdelibs5-dev needs to be "
++"installed. See bugs.launchpad.net, bug #279621 for details."
++msgstr ""
++"在升级时, 如果已经安装了 kdelibs4-dev, 那么需要安装 kdelibs5-dev。参阅 "
++"bugs.launchpad.net 上的 bug #279621 来了解详情。"
++
++#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:44
++#, python-format
++msgid "%i obsolete entries in the status file"
++msgstr "状态文件中包含 %i 项过期条目"
++
++#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:47
++msgid "Obsolete entries in dpkg status"
++msgstr "dpkg 状态中的过期条目"
++
++#. pragma: no cover
++#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:50
++msgid "Obsolete dpkg status entries"
++msgstr "过期的 dpkg 状态条目"
++
++#: ../janitor/plugincore/plugins/remove_lilo_plugin.py:42
++msgid "Remove lilo since grub is also installed.(See bug #314004 for details.)"
++msgstr "由于 grub 已安装,移除 lilo。(详情参见 bug #314004 。)"
++
++msgid ""
++"After your package information was updated the essential package '%s' can "
++"not be found anymore so a bug reporting process is being started."
++msgstr ""
++"更新包信息后就已找不到基本包(essential) '%s',因此即将启动错误报告进程。"
++
++msgid "<b><big>Upgrading Ubuntu to version 12.04</big></b>"
++msgstr "<b><big>正在将 Ubuntu 升级到 12.04 版</big></b>"
++
++msgid "%(count)s update has been selected."
++msgid_plural "%(count)s updates have been selected."
++msgstr[0] "已选择 %(count)s 个更新。"
++
++msgid "%(count_str)s %(download_str)s"
++msgstr "%(count_str)s %(download_str)s"
++
++msgid "Welcome to Ubuntu"
++msgstr "欢迎使用 Ubuntu"
++
++msgid ""
++"These software updates have been issued since this version of Ubuntu was "
++"released."
++msgstr "自正式发布起,Ubuntu 已提供了下列软件更新。"
++
++msgid "Software updates are available for this computer."
++msgstr "当前计算机有可用软件更新。"
++
++msgid "Update Manager"
++msgstr "更新管理器"
++
++msgid "Starting Update Manager"
++msgstr "正在启动更新管理器"
++
++msgid "You are connected via a wireless modem."
++msgstr "您在使用无线调制解调器连接网络。"
++
++msgid "_Install Updates"
++msgstr "安装更新(_I)"
++
++msgid "Checking for a new ubuntu release"
++msgstr "检查新的 Ubuntu 发行版本"
++
++msgid "Your system is up-to-date"
++msgstr "您的系统已为最新"
++
++msgid ""
++"Fetching and installing the upgrade can take several hours. Once the "
++"download has finished, the process cannot be cancelled."
++msgstr "获取并安装升级可能会持续几个小时。一旦下载结束,进程将不能被取消。"
++
++msgid ""
++"If you don't want to install them now, choose \"Update Manager\" from the "
++"Administration menu later."
++msgstr "如果您不想现在安装,稍后可以在“系统管理”菜单选择“更新管理器”进行安装。"
++
++msgid ""
++"This upgrade is running in sandbox (test) mode. All changes are written to "
++"'%s' and will be lost on the next reboot.\n"
++"\n"
++"*No* changes written to a systemdir from now until the next reboot are "
++"permanent."
++msgstr ""
++"这个升级正运行在沙盒(测试)模式下。所有的变更都被写入“%s”并在下次重启时丢"
++"失。\n"
++"\n"
++"从现在起直到下次重启,被写入 systemdir 的变更*不是*永久的。"
++
++msgid "Software updates are available for this computer"
++msgstr "有适合当前系统的软件更新"
++
++msgid "There are no updates to install"
++msgstr "没有可安装的更新"
++
++msgid "The update has already been downloaded, but not installed"
++msgid_plural "The updates have already been downloaded, but not installed"
++msgstr[0] "更新已经下载,但还没有安装。"
++
++msgid ""
++"You will not get any further security fixes or critical updates. Please "
++"upgrade to a later version of Ubuntu Linux."
++msgstr "您不会再收到任何安全更新。请升级到更新版本的 Ubuntu。"
++
++msgid ""
++"If you don't want to install them now, choose \"Update Manager\" from "
++"Applications later."
++msgstr "如果您不想现在安装,可以今后再从应用程序中打开“更新管理器”。"
++
++msgid "0 kB"
++msgstr "0 kB"
++
++msgid "1 kB"
++msgstr "1 kB"
++
++msgid ""
++"The system was unable to get the prerequisites for the upgrade. The upgrade "
++"will abort now and restore the original system state.\n"
++"\n"
++"Please report this as a bug using the command 'ubuntu-bug update-manager' in "
++"a terminal and include the files in /var/log/dist-upgrade/ in the bug report."
++msgstr ""
++"系统无法获取升级所必需的文件。将放弃升级并恢复到原始系统状态。\n"
++"\n"
++"请在终端里输入命令‘ubuntu-bug update-manager’来报告这个 bug。在报告 bug 时附"
++"上位于 /var/log/dist-upgrade/ 的文件。"
++
++msgid ""
++"After your package information was updated the essential package '%s' can "
++"not be found anymore.\n"
++"This indicates a serious error, please report this bug using the command "
++"'ubuntu-bug update-manager' in a terminal and include the files in /var/log/"
++"dist-upgrade/ in the bug report."
++msgstr ""
++"在更新了您的软件包信息之后,系统找不到‘%s’这个必需的软件包。\n"
++"这预示着一个严重错误。在终端里输入命令‘ubuntu-bug update-manager’来报告这个 "
++"bug。在报告 bug 时附上位于 /var/log/dist-upgrade/ 的文件。"
++
++msgid "Your graphics hardware may not be fully supported in Ubuntu 11.04."
++msgstr "您的显卡可能无法完整地被 Ubuntu 11.04 支持。"
++
++msgid ""
++"The support in Ubuntu 11.04 for your intel graphics hardware is limited and "
++"you may encounter problems after the upgrade. Do you want to continue with "
++"the upgrade?"
++msgstr ""
++"Ubuntu 11.04 对您的 intel 显卡支持有限。您可能在升级之后会遇到问题,确定要继"
++"续升级吗?"
++
++msgid ""
++"\n"
++"\n"
++"Please report this bug using the command 'ubuntu-bug update-manager' in a "
++"terminal and include the files in /var/log/dist-upgrade/ in the bug report.\n"
++"%s"
++msgstr ""
++"\n"
++"\n"
++"请在终端里输入命令‘ubuntu-bug update-manager’来报告这个 bug。在报告 bug 时附"
++"上位于 /var/log/dist-upgrade/ 的文件。\n"
++"%s"
++
++msgid ""
++"Preparing the system for the upgrade failed. Please report this using the "
++"command 'ubuntu-bug update-manager' in a terminal and include the files in /"
++"var/log/dist-upgrade/ in the bug report."
++msgstr ""
++"无法获取要升级的系统。请在终端里输入命令‘ubuntu-bug update-manager’来报告这"
++"个 bug。在报告 bug 时附上位于 /var/log/dist-upgrade/ 的文件。"
++
++msgid ""
++"Upgrading the repository information resulted in a invalid file. Please "
++"report this as a bug using the command 'ubuntu-bug update-manager' in a "
++"terminal."
++msgstr ""
++"升级目录信息得到一个非法的文件。请在终端里输入命令‘ubuntu-bug update-"
++"manager’来报告这个 bug。"
++
++msgid ""
++"These software updates have been issued since this version of Ubuntu was "
++"released. If you don't want to install them now, choose \"Update Manager\" "
++"from Applications later."
++msgstr ""
++"这些软件的更新在该版本的 Ubuntu 发行之后被证明有问题。如果您不想现在安装它"
++"们,可以在稍后从系统应用“更新管理器”中选择安装。"
++
++msgid ""
++"These software updates have been issued since this version of Ubuntu was "
++"released. If you don't want to install them now, choose \"Update Manager\" "
++"from the Administration Menu later."
++msgstr ""
++"这些软件的更新在该版本的 Ubuntu 发行之后被证明有问题。如果您不想现在安装它"
++"们,可以在稍后从管理员菜单“更新管理器”中选择安装。"
++
++msgid "%.0f kB"
++msgstr "%.0f kB"
++
++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 "Update Manager exception, 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 "运行检查脚本出现异常。"
++
++msgid "Installing or removing software packages."
++msgstr "正在安装或删除软件包。"
++
++msgid "The system is installing updates. Please do not turn off your computer. "
++msgstr "系统正在安装更新,请不要关闭计算机。"
++
++msgid "If the device is less than 50% charged, please charge it before updating the system."
++msgstr "设备电量不足50%,请充电后再进行系统更新。"
++
++msgid "Application installation control policy not enabled ."
++msgstr "应用安装管控未开启."
++
++msgid "Installation failed! Application is not in the software whitelist list!"
++msgstr "安装失败!软件包不在白名单列表!"
++
++msgid "Installation failed! Application is in the software blacklist list!"
++msgstr "安装失败!软件包在黑名单列表!"
++
++msgid "Application installation in unknown mode ."
++msgstr "应用安装管控策略未知."
++
++msgid "Other tasks are being updated and upgraded, please try again later."
++msgstr "其他任务正在更新升级中,请稍后再试"
++
++msgid "Cancel Upgrade"
++msgstr "取消升级"
++
++msgid "There is no way to rollback to the previous version, there is nothing to rollback."
++msgstr "无法回滚到上一个版本,没有可回滚内容。"
++
++msgid "Check for update exceptions! Please verify that the system deployment is complete."
++msgstr "检查更新异常!请检查系统部署是否完整。"
++
++msgid "Update push is abnormal, and the corresponding branch information cannot be found on the server."
++msgstr "更新推送异常,未在服务端找到相应分支信息。"
++
++msgid "Name of the repository deployed by the current system is empty."
++msgstr "更新检查异常,当前系统部署分支仓库所属信息为空。"
++
++#: ../SystemUpdater/Core/utils.py:753
++msgid "Cancel authentication."
++msgstr "取消认证"
++
++msgid "System upgrade error"
++msgstr "系统更新异常"
+diff --git a/backend-immutable/tests/po/zh_HK.po b/backend-immutable/tests/po/zh_HK.po
+new file mode 100644
+index 0000000..4b147fd
+--- /dev/null
++++ b/backend-immutable/tests/po/zh_HK.po
+@@ -0,0 +1,2712 @@
++msgid ""
++msgstr ""
++"Project-Id-Version: update-manager 0.41.1\n"
++"Report-Msgid-Bugs-To: sebastian.heinlein@web.de\n"
++"POT-Creation-Date: 2012-06-14 00:53+0100\n"
++"PO-Revision-Date: 2012-04-13 00:58+0000\n"
++"Last-Translator: Walter Cheuk <wwycheuk@gmail.com>\n"
++"Language-Team: Chinese (Hong Kong) <zh_HK@li.org>\n"
++"Language: zh_HK\n"
++"MIME-Version: 1.0\n"
++"Content-Type: text/plain; charset=UTF-8\n"
++"Content-Transfer-Encoding: 8bit\n"
++"Plural-Forms: nplurals=1; plural=0;\n"
++"X-Launchpad-Export-Date: 2012-04-17 13:41+0000\n"
++"X-Generator: Launchpad (build 15099)\n"
++
++#. TRANSLATORS: download size of small updates, e.g. "250 kB"
++#: ../DistUpgrade/utils.py:433 ../UpdateManager/Core/utils.py:433
++#, python-format
++msgid "%(size).0f kB"
++msgid_plural "%(size).0f kB"
++msgstr[0] ""
++msgstr[1] ""
++
++#. TRANSLATORS: download size of updates, e.g. "2.3 MB"
++#: ../DistUpgrade/utils.py:436 ../UpdateManager/Core/utils.py:436
++#, python-format
++msgid "%.1f MB"
++msgstr "%.1f MB"
++
++#. TRANSLATORS: %s is a country
++#: ../DistUpgrade/distro.py:206 ../DistUpgrade/distro.py:436
++#, python-format
++msgid "Server for %s"
++msgstr "%s伺服器"
++
++#. More than one server is used. Since we don't handle this case
++#. in the user interface we set "custom servers" to true and
++#. append a list of all used servers
++#: ../DistUpgrade/distro.py:224 ../DistUpgrade/distro.py:230
++#: ../DistUpgrade/distro.py:246
++msgid "Main server"
++msgstr "主要伺服器"
++
++#: ../DistUpgrade/distro.py:250
++msgid "Custom servers"
++msgstr "自訂伺服器"
++
++#: ../DistUpgrade/DistUpgradeAptCdrom.py:142
++msgid "Could not calculate sources.list entry"
++msgstr "無法推算 sources.list 項目"
++
++#: ../DistUpgrade/DistUpgradeAptCdrom.py:251
++msgid ""
++"Unable to locate any package files, perhaps this is not a Ubuntu Disc or the "
++"wrong architecture?"
++msgstr "找不到套件檔案;也許這不是 Ubuntu 光碟,又或者處理器架構不對?"
++
++#: ../DistUpgrade/DistUpgradeAptCdrom.py:294
++msgid "Failed to add the CD"
++msgstr "無法加入光碟"
++
++#: ../DistUpgrade/DistUpgradeAptCdrom.py:295
++#, python-format
++msgid ""
++"There was a error adding the CD, the upgrade will abort. Please report this "
++"as a bug if this is a valid Ubuntu CD.\n"
++"\n"
++"The error message was:\n"
++"'%s'"
++msgstr ""
++"加入光碟時發生錯誤,升級將終止。若確定光碟沒有問題,請將此匯報為臭蟲。\n"
++"\n"
++"錯誤訊息:\n"
++"「%s」"
++
++#: ../DistUpgrade/DistUpgradeCache.py:151
++msgid "Remove package in bad state"
++msgid_plural "Remove packages in bad state"
++msgstr[0] "移除有問題套件"
++
++#: ../DistUpgrade/DistUpgradeCache.py:154
++#, python-format
++msgid ""
++"The package '%s' is in an inconsistent state and needs to be reinstalled, "
++"but no archive can be found for it. Do you want to remove this package now "
++"to continue?"
++msgid_plural ""
++"The packages '%s' are in an inconsistent state and need to be reinstalled, "
++"but no archives can be found for them. Do you want to remove these packages "
++"now to continue?"
++msgstr[0] ""
++"這個套件 '%s' 狀態不一致而需要重新安裝,但找不到它的存檔。您想移除這個套件然"
++"後繼續嗎?"
++
++#. FIXME: not ideal error message, but we just reuse a
++#. existing one here to avoid a new string
++#: ../DistUpgrade/DistUpgradeCache.py:255
++msgid "The server may be overloaded"
++msgstr "伺服器可能負載過大"
++
++#: ../DistUpgrade/DistUpgradeCache.py:368
++msgid "Broken packages"
++msgstr "損毀的套件"
++
++#: ../DistUpgrade/DistUpgradeCache.py:369
++msgid ""
++"Your system contains broken packages that couldn't be fixed with this "
++"software. Please fix them first using synaptic or apt-get before proceeding."
++msgstr ""
++"系統有一些本軟件無法修正的損毀套件。請先以「Synaptic 套件管理員」或 apt-get "
++"修正再繼續。"
++
++#. FIXME: change the text to something more useful
++#: ../DistUpgrade/DistUpgradeCache.py:693
++#, python-format
++msgid ""
++"An unresolvable problem occurred while calculating the upgrade:\n"
++"%s\n"
++"\n"
++" This can be caused by:\n"
++" * Upgrading to a pre-release version of Ubuntu\n"
++" * Running the current pre-release version of Ubuntu\n"
++" * Unofficial software packages not provided by Ubuntu\n"
++"\n"
++msgstr ""
++"為升級進行推算時有問題無法解決:\n"
++"%s\n"
++"\n"
++" 原因可能是:\n"
++" * 要升級至測試版 Ubuntu\n"
++" * 正使用的是測試版 Ubuntu\n"
++" * 非 Ubuntu 官方軟件套件的問題\n"
++"\n"
++
++#: ../DistUpgrade/DistUpgradeCache.py:703
++msgid "This is most likely a transient problem, please try again later."
++msgstr "這通常只是暫時性的問題。請稍候再試。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:706
++msgid ""
++"If none of this applies, then please report this bug using the command "
++"'ubuntu-bug update-manager' in a terminal."
++msgstr ""
++"如全都不對,請在終端機內輸入指令「ubuntu-bug update-manager」回報錯誤。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:711
++#: ../UpdateManager/UpdateManager.py:1031
++msgid "Could not calculate the upgrade"
++msgstr "無法為升級進行推算"
++
++#: ../DistUpgrade/DistUpgradeCache.py:762
++msgid "Error authenticating some packages"
++msgstr "認證一些套件時發生錯誤"
++
++#: ../DistUpgrade/DistUpgradeCache.py:763
++msgid ""
++"It was not possible to authenticate some packages. This may be a transient "
++"network problem. You may want to try again later. See below for a list of "
++"unauthenticated packages."
++msgstr ""
++"系統無法認證一些套件。這可能是由於短暫的網絡問題;您可以稍後再試。以下為沒有"
++"認證的套件。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:783
++#, python-format
++msgid ""
++"The package '%s' is marked for removal but it is in the removal blacklist."
++msgstr "套件「%s」標記作移除,但它在移除黑名單中。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:787
++#, python-format
++msgid "The essential package '%s' is marked for removal."
++msgstr "必備套件「%s」被標記作移除。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:796
++#, python-format
++msgid "Trying to install blacklisted version '%s'"
++msgstr "正在嘗試安裝黑名單版本「%s」"
++
++#: ../DistUpgrade/DistUpgradeCache.py:914
++#, python-format
++msgid "Can't install '%s'"
++msgstr "無法安裝「%s」"
++
++#: ../DistUpgrade/DistUpgradeCache.py:915
++msgid ""
++"It was impossible to install a required package. Please report this as a bug "
++"using 'ubuntu-bug update-manager' in a terminal."
++msgstr ""
++"無法安裝必要的套件。請在終端機內輸入「ubuntu-bug update-manager」回報錯誤。"
++
++#. FIXME: provide a list
++#: ../DistUpgrade/DistUpgradeCache.py:926
++msgid "Can't guess meta-package"
++msgstr "無法估計元套件 (meta-package)"
++
++#: ../DistUpgrade/DistUpgradeCache.py:927
++msgid ""
++"Your system does not contain a ubuntu-desktop, kubuntu-desktop, xubuntu-"
++"desktop or edubuntu-desktop package and it was not possible to detect which "
++"version of Ubuntu you are running.\n"
++" Please install one of the packages above first using synaptic or apt-get "
++"before proceeding."
++msgstr ""
++"您的系統沒有安裝 ubuntu-desktop、kubuntu-desktop、xubuntu-desktop 或 "
++"edubuntu-desktop 套件,因此無法偵測正在使用那個版本的 Ubuntu。\n"
++" 請先以「Synaptic 套件管理員」或 apt-get 安裝上述其中一個套件再繼續。"
++
++#: ../DistUpgrade/DistUpgradeController.py:114
++msgid "Reading cache"
++msgstr "正在讀取快取"
++
++#: ../DistUpgrade/DistUpgradeController.py:223
++msgid "Unable to get exclusive lock"
++msgstr "無法取得(使用)排他鎖定"
++
++#: ../DistUpgrade/DistUpgradeController.py:224
++msgid ""
++"This usually means that another package management application (like apt-get "
++"or aptitude) already running. Please close that application first."
++msgstr ""
++"這通常表示有其他的套件管理員程式(如 apt-get 或 aptitude)正在執行。請先關閉"
++"這些應用程式。"
++
++#: ../DistUpgrade/DistUpgradeController.py:257
++msgid "Upgrading over remote connection not supported"
++msgstr "不支援透過遠端連線升級"
++
++#: ../DistUpgrade/DistUpgradeController.py:258
++msgid ""
++"You are running the upgrade over a remote ssh connection with a frontend "
++"that does not support this. Please try a text mode upgrade with 'do-release-"
++"upgrade'.\n"
++"\n"
++"The upgrade will abort now. Please try without ssh."
++msgstr ""
++"您正在透過遠端 ssh 連線的前端介面執行更新,而此介面不支援。請試試純文字模式下"
++"以 'do-release-upgrade' 進行更新。\n"
++"\n"
++"目前更新將會中止。請透過非 ssh 連線重試。"
++
++#: ../DistUpgrade/DistUpgradeController.py:272
++msgid "Continue running under SSH?"
++msgstr "繼續執行於 SSH 中?"
++
++#: ../DistUpgrade/DistUpgradeController.py:273
++#, python-format
++msgid ""
++"This session appears to be running under ssh. It is not recommended to "
++"perform a upgrade over ssh currently because in case of failure it is harder "
++"to recover.\n"
++"\n"
++"If you continue, an additional ssh daemon will be started at port '%s'.\n"
++"Do you want to continue?"
++msgstr ""
++"此連線階段似乎是在 ssh 下執行。目前不建議在 ssh 連線下進行升級,因為若發生失"
++"敗將會較難以修復。\n"
++"\n"
++"若您繼續,一個額外的 ssh 背景程序將會啟動在 '%s' 連接埠。\n"
++"您想要繼續嗎?"
++
++#: ../DistUpgrade/DistUpgradeController.py:287
++msgid "Starting additional sshd"
++msgstr "啟動後備 sshd 中"
++
++#: ../DistUpgrade/DistUpgradeController.py:288
++#, python-format
++msgid ""
++"To make recovery in case of failure easier, an additional sshd will be "
++"started on port '%s'. If anything goes wrong with the running ssh you can "
++"still connect to the additional one.\n"
++msgstr ""
++"為在失敗時更易進行修復,一個後備 sshd 將在‘%s’埠被啟動。如果使用中的 ssh 有任"
++"何問題,您仍可以連接後備的 sshd 。\n"
++
++#: ../DistUpgrade/DistUpgradeController.py:296
++#, python-format
++msgid ""
++"If you run a firewall, you may need to temporarily open this port. As this "
++"is potentially dangerous it's not done automatically. You can open the port "
++"with e.g.:\n"
++"'%s'"
++msgstr ""
++"若有執行防火牆,可能需要暫時開啟此連接埠。由於此動作有潛在危險,系統不會自動"
++"執行。可以這樣開啟連接埠:\n"
++"「%s」"
++
++#: ../DistUpgrade/DistUpgradeController.py:368
++#: ../DistUpgrade/DistUpgradeController.py:413
++msgid "Can not upgrade"
++msgstr "無法升級"
++
++#: ../DistUpgrade/DistUpgradeController.py:369
++#, python-format
++msgid "An upgrade from '%s' to '%s' is not supported with this tool."
++msgstr "這個工具不支援從‘%s’到‘%s’的升級"
++
++#: ../DistUpgrade/DistUpgradeController.py:378
++msgid "Sandbox setup failed"
++msgstr "沙堆(Sandbox)架設失敗"
++
++#: ../DistUpgrade/DistUpgradeController.py:379
++msgid "It was not possible to create the sandbox environment."
++msgstr "不可能建立沙堆(sandbox)環境。"
++
++#: ../DistUpgrade/DistUpgradeController.py:385
++msgid "Sandbox mode"
++msgstr "沙堆(Sandbox)模式"
++
++#: ../DistUpgrade/DistUpgradeController.py:386
++#, python-format
++msgid ""
++"This upgrade is running in sandbox (test) mode. All changes are written to "
++"'%s' and will be lost on the next reboot.\n"
++"\n"
++"*No* changes written to a system directory from now until the next reboot "
++"are permanent."
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeController.py:414
++msgid ""
++"Your python install is corrupted. Please fix the '/usr/bin/python' symlink."
++msgstr "您的 python 安裝已毀損。請修正 ‘/usr/bin/python’ 的符號連結。"
++
++#: ../DistUpgrade/DistUpgradeController.py:440
++msgid "Package 'debsig-verify' is installed"
++msgstr "套件 'debsig-verify' 安裝完成。"
++
++#: ../DistUpgrade/DistUpgradeController.py:441
++msgid ""
++"The upgrade can not continue with that package installed.\n"
++"Please remove it with synaptic or 'apt-get remove debsig-verify' first and "
++"run the upgrade again."
++msgstr ""
++"該已安裝套件令升級無法繼續,請先以「Synaptic 套件管理員」或「apt-get remove "
++"debsig-verify」指令將其移除再進行升級。"
++
++#: ../DistUpgrade/DistUpgradeController.py:453
++#, python-format
++msgid "Can not write to '%s'"
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeController.py:454
++#, python-format
++msgid ""
++"Its not possible to write to the system directory '%s' on your system. The "
++"upgrade can not continue.\n"
++"Please make sure that the system directory is writable."
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeController.py:465
++msgid "Include latest updates from the Internet?"
++msgstr "包括互聯網上的最新更新嗎?"
++
++#: ../DistUpgrade/DistUpgradeController.py:466
++msgid ""
++"The upgrade system can use the internet to automatically download the latest "
++"updates and install them during the upgrade.  If you have a network "
++"connection this is highly recommended.\n"
++"\n"
++"The upgrade will take longer, but when it is complete, your system will be "
++"fully up to date.  You can choose not to do this, but you should install the "
++"latest updates soon after upgrading.\n"
++"If you answer 'no' here, the network is not used at all."
++msgstr ""
++"升級系統可自動由互聯網下載最新更新並在升級時安裝。如有網絡連線,建議使用這方"
++"法。\n"
++"\n"
++"升級的時間會比較久,但完成後,系統就會完全在最新狀態。您可以選擇現在不進行這"
++"工作,但是在升級後,應該要盡快安裝最新的更新。\n"
++"如在此回答「否」,將完全不會使用網絡。"
++
++#: ../DistUpgrade/DistUpgradeController.py:686
++#, python-format
++msgid "disabled on upgrade to %s"
++msgstr "因升級至 %s 停用"
++
++#: ../DistUpgrade/DistUpgradeController.py:713
++msgid "No valid mirror found"
++msgstr "找不到有效的鏡像站"
++
++#: ../DistUpgrade/DistUpgradeController.py:714
++#, python-format
++msgid ""
++"While scanning your repository information no mirror entry for the upgrade "
++"was found. This can happen if you run a internal mirror or if the mirror "
++"information is out of date.\n"
++"\n"
++"Do you want to rewrite your 'sources.list' file anyway? If you choose 'Yes' "
++"here it will update all '%s' to '%s' entries.\n"
++"If you select 'No' the upgrade will cancel."
++msgstr ""
++"掃描套件庫資料時沒有發現可提供升級的鏡像站。如果使用的是內部鏡像站或鏡像站資"
++"料已經過時,就會發生這種情況。\n"
++"\n"
++"是否無論如何都希望覆寫 'sources.list' 檔案?如果在此選擇「是」則會將所有 "
++"'%s' 項目更新成 '%s'。\n"
++"如果選擇「否」,則會取消更新。"
++
++#. hm, still nothing useful ...
++#: ../DistUpgrade/DistUpgradeController.py:734
++msgid "Generate default sources?"
++msgstr "產生預設的來源?"
++
++#: ../DistUpgrade/DistUpgradeController.py:735
++#, python-format
++msgid ""
++"After scanning your 'sources.list' no valid entry for '%s' was found.\n"
++"\n"
++"Should default entries for '%s' be added? If you select 'No', the upgrade "
++"will cancel."
++msgstr ""
++"在掃描您的 'sources.list' 後,沒找到與 '%s' 有效的項目。\n"
++"\n"
++"要新增 '%s' 的預設項目嗎?如果選擇「否」,則會取消升級。"
++
++#: ../DistUpgrade/DistUpgradeController.py:770
++msgid "Repository information invalid"
++msgstr "套件庫資料無效"
++
++#: ../DistUpgrade/DistUpgradeController.py:771
++msgid ""
++"Upgrading the repository information resulted in a invalid file so a bug "
++"reporting process is being started."
++msgstr "因更新套件庫資料導致檔案無效,故啟動錯誤報告程序。"
++
++#: ../DistUpgrade/DistUpgradeController.py:778
++msgid "Third party sources disabled"
++msgstr "已停用第三方來源"
++
++#: ../DistUpgrade/DistUpgradeController.py:779
++msgid ""
++"Some third party entries in your sources.list were disabled. You can re-"
++"enable them after the upgrade with the 'software-properties' tool or your "
++"package manager."
++msgstr ""
++"部份在 sources.list 的第三方項目已經停用。升級完成後可以「軟件來源(software-"
++"properties)」工具或套件管理員重新啟用。"
++
++#: ../DistUpgrade/DistUpgradeController.py:819
++msgid "Package in inconsistent state"
++msgid_plural "Packages in inconsistent state"
++msgstr[0] "套件在不一致狀態"
++
++#: ../DistUpgrade/DistUpgradeController.py:822
++#, python-format
++msgid ""
++"The package '%s' is in an inconsistent state and needs to be reinstalled, "
++"but no archive can be found for it. Please reinstall the package manually or "
++"remove it from the system."
++msgid_plural ""
++"The packages '%s' are in an inconsistent state and need to be reinstalled, "
++"but no archive can be found for them. Please reinstall the packages manually "
++"or remove them from the system."
++msgstr[0] ""
++"這個套件 '%s' 狀態不一致而需要重新安裝,但找不到其存檔套件。請手動重新安裝或"
++"將其由系統移除。"
++
++#: ../DistUpgrade/DistUpgradeController.py:870
++msgid "Error during update"
++msgstr "更新時發生錯誤"
++
++#: ../DistUpgrade/DistUpgradeController.py:871
++msgid ""
++"A problem occurred during the update. This is usually some sort of network "
++"problem, please check your network connection and retry."
++msgstr "更新時發生錯誤。這可能是某些網絡問題,請檢查網絡連線後再試。"
++
++#. print("on_button_install_clicked")
++#: ../DistUpgrade/DistUpgradeController.py:880
++#: ../UpdateManager/UpdateManager.py:757
++msgid "Not enough free disk space"
++msgstr "磁碟空間不足"
++
++#: ../DistUpgrade/DistUpgradeController.py:881
++#, python-format
++msgid ""
++"The upgrade has aborted. The upgrade needs a total of %s free space on disk "
++"'%s'. Please free at least an additional %s of disk space on '%s'. Empty "
++"your trash and remove temporary packages of former installations using 'sudo "
++"apt-get clean'."
++msgstr ""
++"已放棄升級。升級程序總共需要  %s 可用空間於磁碟「%s」。請釋放至少額外 %s 的磁"
++"碟空間於磁碟「%s」。清理您的回收筒,並使用 'sudo apt-get clean' 來移除之前安"
++"裝時的暫時性套件。"
++
++#. calc the dist-upgrade and see if the removals are ok/expected
++#. do the dist-upgrade
++#: ../DistUpgrade/DistUpgradeController.py:910
++#: ../DistUpgrade/DistUpgradeController.py:1692
++msgid "Calculating the changes"
++msgstr "正在推算改動"
++
++#. ask the user
++#: ../DistUpgrade/DistUpgradeController.py:942
++msgid "Do you want to start the upgrade?"
++msgstr "想要開始更新嗎?"
++
++#: ../DistUpgrade/DistUpgradeController.py:1008
++msgid "Upgrade canceled"
++msgstr "升級取消了"
++
++#: ../DistUpgrade/DistUpgradeController.py:1009
++msgid ""
++"The upgrade will cancel now and the original system state will be restored. "
++"You can resume the upgrade at a later time."
++msgstr "現在將取消升級,並將系統還原至原來狀態。您可以在之後繼續升級。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1015
++#: ../DistUpgrade/DistUpgradeController.py:1149
++msgid "Could not download the upgrades"
++msgstr "無法下載升級套件"
++
++#: ../DistUpgrade/DistUpgradeController.py:1016
++msgid ""
++"The upgrade has aborted. Please check your Internet connection or "
++"installation media and try again. All files downloaded so far have been kept."
++msgstr ""
++"升級已中止。請檢查您的互聯網連線,或安裝媒體並重試。所有目前已下載的檔案都會"
++"被保留。"
++
++#. FIXME: strings are not good, but we are in string freeze
++#. currently
++#: ../DistUpgrade/DistUpgradeController.py:1100
++#: ../DistUpgrade/DistUpgradeController.py:1137
++#: ../DistUpgrade/DistUpgradeController.py:1242
++msgid "Error during commit"
++msgstr "提交時發生錯誤"
++
++#. generate a new cache
++#: ../DistUpgrade/DistUpgradeController.py:1102
++#: ../DistUpgrade/DistUpgradeController.py:1139
++#: ../DistUpgrade/DistUpgradeController.py:1281
++msgid "Restoring original system state"
++msgstr "回復原有系統狀態"
++
++#: ../DistUpgrade/DistUpgradeController.py:1103
++#: ../DistUpgrade/DistUpgradeController.py:1118
++#: ../DistUpgrade/DistUpgradeController.py:1140
++msgid "Could not install the upgrades"
++msgstr "無法安裝升級套件"
++
++#. invoke the frontend now and show a error message
++#: ../DistUpgrade/DistUpgradeController.py:1108
++msgid ""
++"The upgrade has aborted. Your system could be in an unusable state. A "
++"recovery will run now (dpkg --configure -a)."
++msgstr ""
++"已放棄升級。系統可能會處於不穩定狀態。現在會執行復原程序 (dpkg --configure -"
++"a)。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1113
++#, python-format
++msgid ""
++"\n"
++"\n"
++"Please report this bug in a browser at http://bugs.launchpad.net/ubuntu/"
++"+source/update-manager/+filebug and attach the files in /var/log/dist-"
++"upgrade/ to the bug report.\n"
++"%s"
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeController.py:1150
++msgid ""
++"The upgrade has aborted. Please check your Internet connection or "
++"installation media and try again. "
++msgstr "已放棄升級。請檢查您的互聯網連線或安裝媒體,接著再試一次。 "
++
++#: ../DistUpgrade/DistUpgradeController.py:1230
++msgid "Remove obsolete packages?"
++msgstr "移除廢棄的套件?"
++
++#: ../DistUpgrade/DistUpgradeController.py:1231
++#: ../DistUpgrade/DistUpgrade.ui.h:8
++msgid "_Keep"
++msgstr "保留(_K)"
++
++#: ../DistUpgrade/DistUpgradeController.py:1231
++msgid "_Remove"
++msgstr "移除(_R)"
++
++#: ../DistUpgrade/DistUpgradeController.py:1243
++msgid ""
++"A problem occurred during the clean-up. Please see the below message for "
++"more information. "
++msgstr "進行清理時發生問題。詳情請參閱以下訊息。 "
++
++#. FIXME: instead of error out, fetch and install it
++#. here
++#: ../DistUpgrade/DistUpgradeController.py:1319
++msgid "Required depends is not installed"
++msgstr "必需的相依套件未安裝"
++
++#: ../DistUpgrade/DistUpgradeController.py:1320
++#, python-format
++msgid "The required dependency '%s' is not installed. "
++msgstr "必需的相依套件「%s」未安裝。 "
++
++#. sanity check (check for ubuntu-desktop, brokenCache etc)
++#. then open the cache (again)
++#: ../DistUpgrade/DistUpgradeController.py:1588
++#: ../DistUpgrade/DistUpgradeController.py:1653
++msgid "Checking package manager"
++msgstr "正在檢查套件管理員"
++
++#: ../DistUpgrade/DistUpgradeController.py:1593
++msgid "Preparing the upgrade failed"
++msgstr "準備升級失敗"
++
++#: ../DistUpgrade/DistUpgradeController.py:1594
++msgid ""
++"Preparing the system for the upgrade failed so a bug reporting process is "
++"being started."
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeController.py:1608
++msgid "Getting upgrade prerequisites failed"
++msgstr "取得升級先決元件失敗"
++
++#: ../DistUpgrade/DistUpgradeController.py:1609
++msgid ""
++"The system was unable to get the prerequisites for the upgrade. The upgrade "
++"will abort now and restore the original system state.\n"
++"\n"
++"Additionally, a bug reporting process is being started."
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeController.py:1637
++msgid "Updating repository information"
++msgstr "更新套件庫資料"
++
++#: ../DistUpgrade/DistUpgradeController.py:1644
++msgid "Failed to add the cdrom"
++msgstr "無法加入光碟"
++
++#: ../DistUpgrade/DistUpgradeController.py:1645
++msgid "Sorry, adding the cdrom was not successful."
++msgstr "很抱歉,沒有成功加入光碟。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1673
++msgid "Invalid package information"
++msgstr "套件資訊無效"
++
++#: ../DistUpgrade/DistUpgradeController.py:1674
++msgid "After updating your package "
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeController.py:1698
++#: ../DistUpgrade/DistUpgradeController.py:1750
++msgid "Fetching"
++msgstr "提取中"
++
++#: ../DistUpgrade/DistUpgradeController.py:1704
++#: ../DistUpgrade/DistUpgradeController.py:1754
++msgid "Upgrading"
++msgstr "升級中"
++
++#. don't abort here, because it would restore the sources.list
++#: ../DistUpgrade/DistUpgradeController.py:1709
++#: ../DistUpgrade/DistUpgradeController.py:1756
++#: ../DistUpgrade/DistUpgradeController.py:1763
++#: ../DistUpgrade/DistUpgradeController.py:1774
++msgid "Upgrade complete"
++msgstr "升級完成"
++
++#: ../DistUpgrade/DistUpgradeController.py:1710
++#: ../DistUpgrade/DistUpgradeController.py:1757
++#: ../DistUpgrade/DistUpgradeController.py:1764
++msgid ""
++"The upgrade has completed but there were errors during the upgrade process."
++msgstr "升級已經完成,但在升級過程中有發生錯誤。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1717
++msgid "Searching for obsolete software"
++msgstr "搜尋廢棄的軟件中"
++
++#: ../DistUpgrade/DistUpgradeController.py:1726
++msgid "System upgrade is complete."
++msgstr "系統升級完成。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1775
++msgid "The partial upgrade was completed."
++msgstr "部份升級完成。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:204
++msgid "evms in use"
++msgstr "有軟件正使用 evms"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:205
++msgid ""
++"Your system uses the 'evms' volume manager in /proc/mounts. The 'evms' "
++"software is no longer supported, please switch it off and run the upgrade "
++"again when this is done."
++msgstr ""
++"您的系統於 /proc/mounts 使用 'evms' volume 管理程式。'evms' 軟件已不受支援,"
++"請將其關閉再執行升級工作。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:502
++msgid "Your graphics hardware may not be fully supported in Ubuntu 12.04 LTS."
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:504
++msgid ""
++"The support in Ubuntu 12.04 LTS for your Intel graphics hardware is limited "
++"and you may encounter problems after the upgrade. For more information see "
++"https://wiki.ubuntu.com/X/Bugs/UpdateManagerWarningForI8xx Do you want to "
++"continue with the upgrade?"
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:526
++#: ../DistUpgrade/DistUpgradeQuirks.py:554
++#: ../DistUpgrade/DistUpgradeQuirks.py:581
++msgid ""
++"Upgrading may reduce desktop effects, and performance in games and other "
++"graphically intensive programs."
++msgstr "升級可能減低桌面特效和遊戲及其他著重圖形程式的表現。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:530
++#: ../DistUpgrade/DistUpgradeQuirks.py:558
++msgid ""
++"This computer is currently using the NVIDIA 'nvidia' graphics driver. No "
++"version of this driver is available that works with your video card in "
++"Ubuntu 10.04 LTS.\n"
++"\n"
++"Do you want to continue?"
++msgstr ""
++"這個電腦目前正使用 NVIDIA 的「nvidia」圖形驅動程式。這個驅動程式沒有任何版本"
++"可在 Ubuntu 10.04 LTS 中正常驅動您的硬件。\n"
++"\n"
++"是否要繼續?"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:585
++msgid ""
++"This computer is currently using the AMD 'fglrx' graphics driver. No version "
++"of this driver is available that works with your hardware in Ubuntu 10.04 "
++"LTS.\n"
++"\n"
++"Do you want to continue?"
++msgstr ""
++"這個電腦目前正使用 AMD 的「fglrx」圖形驅動程式。這個驅動程式沒有任何版本可在 "
++"Ubuntu 10.04 LTS 中正常驅動您的硬件。\n"
++"\n"
++"是否要繼續?"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:615
++msgid "No i686 CPU"
++msgstr "非 i686 處理器"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:616
++msgid ""
++"Your system uses an i586 CPU or a CPU that does not have the 'cmov' "
++"extension. All packages were built with optimizations requiring i686 as the "
++"minimal architecture. It is not possible to upgrade your system to a new "
++"Ubuntu release with this hardware."
++msgstr ""
++"您的系統使用 i586 處理器,或是不支援「cmov」擴充功能的處理器。所有套件都以 "
++"i686 架構為最佳化目標來建置,所以處理器至少需要有 i686 等級。對於目前的硬件來"
++"說,無法將系統升級到新的 Ubuntu 發行版。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:652
++msgid "No ARMv6 CPU"
++msgstr "非 ARMv6 處理器"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:653
++msgid ""
++"Your system uses an ARM CPU that is older than the ARMv6 architecture. All "
++"packages in karmic were built with optimizations requiring ARMv6 as the "
++"minimal architecture. It is not possible to upgrade your system to a new "
++"Ubuntu release with this hardware."
++msgstr ""
++"您系統使用的 ARM 處理器舊於 ARMv6 架構。所有 karmic 套件都以 ARMv6 架構為最佳"
++"化目標來建置,所以處理器至少需要有 ARMv6 等級。對於目前的硬件來說,無法將系統"
++"升級到新的 Ubuntu 發行版。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:673
++msgid "No init available"
++msgstr "無法初始化"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:674
++msgid ""
++"Your system appears to be a virtualised environment without an init daemon, "
++"e.g. Linux-VServer. Ubuntu 10.04 LTS cannot function within this type of "
++"environment, requiring an update to your virtual machine configuration "
++"first.\n"
++"\n"
++"Are you sure you want to continue?"
++msgstr ""
++"您的系統似乎在虛擬化環境中且無初始化程序,例如 Linux-VServer。Ubuntu 10.04 "
++"LTS 無法在此環境中執行,需要先更新您的虛擬機器設定。\n"
++"\n"
++"您確定想要繼續?"
++
++#: ../DistUpgrade/DistUpgradeMain.py:65
++msgid "Sandbox upgrade using aufs"
++msgstr "使用 aufs 作為沙堆升級"
++
++#: ../DistUpgrade/DistUpgradeMain.py:67
++msgid "Use the given path to search for a cdrom with upgradable packages"
++msgstr "使用指定路徑搜尋附有升級套件的光碟"
++
++#: ../DistUpgrade/DistUpgradeMain.py:73
++msgid ""
++"Use frontend. Currently available: \n"
++"DistUpgradeViewText, DistUpgradeViewGtk, DistUpgradeViewKDE"
++msgstr ""
++"使用前端介面。可供選擇的有: \n"
++"DistUpgradeViewText (純文字), DistUpgradeViewGtk (GTK+), DistUpgradeViewKDE "
++"(KDE)"
++
++#: ../DistUpgrade/DistUpgradeMain.py:76
++msgid "*DEPRECATED* this option will be ignored"
++msgstr "*已棄用* 這個選項會被忽略"
++
++#: ../DistUpgrade/DistUpgradeMain.py:79
++msgid "Perform a partial upgrade only (no sources.list rewriting)"
++msgstr "只進行部份更新 (無須修改 sources.list)"
++
++#: ../DistUpgrade/DistUpgradeMain.py:82
++msgid "Disable GNU screen support"
++msgstr "停用 GNU screen 支援"
++
++#: ../DistUpgrade/DistUpgradeMain.py:84
++msgid "Set datadir"
++msgstr "設定資料目錄"
++
++#. print("mediaChange %s %s" % (medium, drive))
++#: ../DistUpgrade/DistUpgradeViewGtk.py:114
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:117
++#: ../DistUpgrade/DistUpgradeViewKDE.py:195
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:155
++#, python-format
++msgid "Please insert '%s' into the drive '%s'"
++msgstr "請將‘%s’放入光碟機‘%s’"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:135
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:138
++#: ../DistUpgrade/DistUpgradeViewKDE.py:209
++msgid "Fetching is complete"
++msgstr "提取完成"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:146
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:149
++#: ../DistUpgrade/DistUpgradeViewKDE.py:222
++#, python-format
++msgid "Fetching file %li of %li at %sB/s"
++msgstr "正提取第 %li 個檔案 (共 %li 個),速度為 %sB/秒"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:149
++#: ../DistUpgrade/DistUpgradeViewGtk.py:296
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:152
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:309
++#: ../DistUpgrade/DistUpgradeViewKDE.py:223
++#: ../DistUpgrade/DistUpgradeViewKDE.py:371
++#, python-format
++msgid "About %s remaining"
++msgstr "大約還有 %s"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:152
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:155
++#: ../DistUpgrade/DistUpgradeViewKDE.py:225
++#, python-format
++msgid "Fetching file %li of %li"
++msgstr "正提取第 %li 個檔案 (共 %li 個)"
++
++#. FIXME: add support for the timeout
++#. of the terminal (to display something useful then)
++#. -> longer term, move this code into python-apt
++#: ../DistUpgrade/DistUpgradeViewGtk.py:183
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:186
++#: ../DistUpgrade/DistUpgradeViewKDE.py:262
++msgid "Applying changes"
++msgstr "正在套用改動"
++
++#. we do not report followup errors from earlier failures
++#: ../DistUpgrade/DistUpgradeViewGtk.py:208
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:212
++#: ../DistUpgrade/DistUpgradeViewKDE.py:275
++msgid "dependency problems - leaving unconfigured"
++msgstr "相依關係問題 - 仍未被設定"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:213
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:217
++#: ../DistUpgrade/DistUpgradeViewKDE.py:277
++#, python-format
++msgid "Could not install '%s'"
++msgstr "無法安裝‘%s’"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:214
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:218
++#: ../DistUpgrade/DistUpgradeViewKDE.py:278
++#, python-format
++msgid ""
++"The upgrade will continue but the '%s' package may not be in a working "
++"state. Please consider submitting a bug report about it."
++msgstr "更新會繼續,但 '%s' 套件可能無法運作。請考慮提交關於該套件的臭蟲報告。"
++
++#. self.expander.set_expanded(True)
++#: ../DistUpgrade/DistUpgradeViewGtk.py:231
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:235
++#: ../DistUpgrade/DistUpgradeViewKDE.py:299
++#, python-format
++msgid ""
++"Replace the customized configuration file\n"
++"'%s'?"
++msgstr ""
++"是否取代已有的設定檔案\n"
++"「%s」?"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:232
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:236
++#: ../DistUpgrade/DistUpgradeViewKDE.py:300
++msgid ""
++"You will lose any changes you have made to this configuration file if you "
++"choose to replace it with a newer version."
++msgstr "如選擇以新版取代,會失去您改動過的設定。"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:251
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:256
++#: ../DistUpgrade/DistUpgradeViewKDE.py:323
++msgid "The 'diff' command was not found"
++msgstr "找不到‘diff’指令"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:464
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:477
++#: ../DistUpgrade/DistUpgradeViewText.py:92
++msgid "A fatal error occurred"
++msgstr "發生嚴重錯誤"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:465
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:478
++msgid ""
++"Please report this as a bug (if you haven't already) and include the files /"
++"var/log/dist-upgrade/main.log and /var/log/dist-upgrade/apt.log in your "
++"report. The upgrade has aborted.\n"
++"Your original sources.list was saved in /etc/apt/sources.list.distUpgrade."
++msgstr ""
++"請回報此錯誤 (若您尚未回報) 並將檔案 /var/log/dist-upgrade/main.log 與 /var/"
++"log/dist-upgrade/apt.log 附在報告。升級程序已中止。\n"
++"您原先的 sources.list 儲存於 /etc/apt/sources.list.distUpgrade"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:482
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:495
++msgid "Ctrl-c pressed"
++msgstr "按下 Ctrl+c"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:483
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:496
++msgid ""
++"This will abort the operation and may leave the system in a broken state. "
++"Are you sure you want to do that?"
++msgstr "這將會中止操作並可能令系統在不完整的狀態。您確定要進行嗎?"
++
++#. append warning
++#: ../DistUpgrade/DistUpgradeViewGtk.py:631
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:629
++msgid "To prevent data loss close all open applications and documents."
++msgstr "為避免遺失資料,請關閉所有已開啟的程式及文件。"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:645
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:643
++#, python-format
++msgid "No longer supported by Canonical (%s)"
++msgstr "不再受 Canonical 支援 (%s 個)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:646
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:644
++#, python-format
++msgid "<b>Downgrade (%s)</b>"
++msgstr "<b>降級 (%s)</b>"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:647
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:645
++#, python-format
++msgid "Remove (%s)"
++msgstr "移除 (%s 個)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:648
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:646
++#, python-format
++msgid "No longer needed (%s)"
++msgstr "不再需要 (%s 個)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:649
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:647
++#, python-format
++msgid "Install (%s)"
++msgstr "安裝 (%s 個)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:650
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:648
++#, python-format
++msgid "Upgrade (%s)"
++msgstr "升級 (%s 個)"
++
++#. change = QMessageBox.question(None, _("Media Change"), msg, QMessageBox.Ok, QMessageBox.Cancel)
++#: ../DistUpgrade/DistUpgradeViewKDE.py:196
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:157
++msgid "Media Change"
++msgstr "媒體變更"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:335
++msgid "Show Difference >>>"
++msgstr "顯示差異 >>>"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:338
++msgid "<<< Hide Difference"
++msgstr "<<< 隱藏差異"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:554
++msgid "Error"
++msgstr "錯誤"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:568
++msgid "&Cancel"
++msgstr "取消(&C)"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:572
++#: ../DistUpgrade/DistUpgradeViewKDE.py:813
++msgid "&Close"
++msgstr "關閉(&C)"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:618
++msgid "Show Terminal >>>"
++msgstr "顯示終端畫面 >>>"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:621
++msgid "<<< Hide Terminal"
++msgstr "<<< 隱藏終端畫面"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:701
++msgid "Information"
++msgstr "資訊"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:751
++#: ../DistUpgrade/DistUpgradeViewKDE.py:796
++#: ../DistUpgrade/DistUpgradeViewKDE.py:799 ../DistUpgrade/DistUpgrade.ui.h:7
++msgid "Details"
++msgstr "詳情"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:777
++#, python-format
++msgid "No longer supported %s"
++msgstr "不再受支援 %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:779
++#, python-format
++msgid "Remove %s"
++msgstr "移除 %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:781
++#: ../DistUpgrade/DistUpgradeViewText.py:182
++#, python-format
++msgid "Remove (was auto installed) %s"
++msgstr "移除 (自動安裝的) %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:783
++#, python-format
++msgid "Install %s"
++msgstr "安裝 %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:785
++#, python-format
++msgid "Upgrade %s"
++msgstr "升級 %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:809
++#: ../DistUpgrade/DistUpgradeViewText.py:230
++msgid "Restart required"
++msgstr "需要重新開機"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:809
++msgid "<b><big>Restart the system to complete the upgrade</big></b>"
++msgstr "<b><big>重新啟動系統以完成更新</big></b>"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:812 ../DistUpgrade/DistUpgrade.ui.h:14
++#: ../data/gtkbuilder/UpdateManager.ui.h:26
++msgid "_Restart Now"
++msgstr "現在重新啟動(_R)"
++
++#. FIXME make this user friendly
++#: ../DistUpgrade/DistUpgradeViewKDE.py:830
++msgid ""
++"<b><big>Cancel the running upgrade?</big></b>\n"
++"\n"
++"The system could be in an unusable state if you cancel the upgrade. You are "
++"strongly advised to resume the upgrade."
++msgstr ""
++"<b><big>取消進行中的升級嗎?</big></b>\n"
++"\n"
++"如果您取消升級,系統可能會在不穩定的狀態。強烈建議您繼續升級工作。"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:834
++msgid "Cancel Upgrade?"
++msgstr "要取消升級嗎?"
++
++#: ../DistUpgrade/DistUpgradeView.py:61
++#, python-format
++msgid "%li day"
++msgid_plural "%li days"
++msgstr[0] "%li 日"
++
++#: ../DistUpgrade/DistUpgradeView.py:63
++#, python-format
++msgid "%li hour"
++msgid_plural "%li hours"
++msgstr[0] "%li 小時"
++
++#: ../DistUpgrade/DistUpgradeView.py:65
++#, python-format
++msgid "%li minute"
++msgid_plural "%li minutes"
++msgstr[0] "%li 分鐘"
++
++#: ../DistUpgrade/DistUpgradeView.py:66
++#, python-format
++msgid "%li second"
++msgid_plural "%li seconds"
++msgstr[0] "%li 秒"
++
++#. TRANSLATORS: you can alter the ordering of the remaining time
++#. information here if you shuffle %(str_days)s %(str_hours)s %(str_minutes)s
++#. around. Make sure to keep all '$(str_*)s' in the translated string
++#. and do NOT change anything appart from the ordering.
++#.
++#. %(str_hours)s will be either "1 hour" or "2 hours" depending on the
++#. plural form
++#.
++#. Note: most western languages will not need to change this
++#: ../DistUpgrade/DistUpgradeView.py:82
++#, python-format
++msgid "%(str_days)s %(str_hours)s"
++msgstr "%(str_days)s零 %(str_hours)s"
++
++#. TRANSLATORS: you can alter the ordering of the remaining time
++#. information here if you shuffle %(str_hours)s %(str_minutes)s
++#. around. Make sure to keep all '$(str_*)s' in the translated string
++#. and do NOT change anything appart from the ordering.
++#.
++#. %(str_hours)s will be either "1 hour" or "2 hours" depending on the
++#. plural form
++#.
++#. Note: most western languages will not need to change this
++#: ../DistUpgrade/DistUpgradeView.py:100
++#, python-format
++msgid "%(str_hours)s %(str_minutes)s"
++msgstr "%(str_hours)s又 %(str_minutes)s"
++
++#. 56 kbit
++#. 1Mbit = 1024 kbit
++#: ../DistUpgrade/DistUpgradeView.py:151
++#, python-format
++msgid ""
++"This download will take about %s with a 1Mbit DSL connection and about %s "
++"with a 56k modem."
++msgstr "這次下載所需時間在 1M 寬頻連線大約要 %s,用 56k 數據機大約要 %s。"
++
++#. if we have a estimated speed, use it
++#: ../DistUpgrade/DistUpgradeView.py:155
++#, python-format
++msgid "This download will take about %s with your connection. "
++msgstr "按照您的連線速度,此下載會花約 %s。 "
++
++#. Declare these translatable strings from the .ui files here so that
++#. xgettext picks them up.
++#: ../DistUpgrade/DistUpgradeView.py:259 ../DistUpgrade/DistUpgrade.ui.h:21
++msgid "Preparing to upgrade"
++msgstr "準備升級"
++
++#: ../DistUpgrade/DistUpgradeView.py:260
++msgid "Getting new software channels"
++msgstr "取得新軟件頻道中"
++
++#: ../DistUpgrade/DistUpgradeView.py:261 ../DistUpgrade/DistUpgrade.ui.h:23
++msgid "Getting new packages"
++msgstr "取得新套件"
++
++#: ../DistUpgrade/DistUpgradeView.py:262 ../DistUpgrade/DistUpgrade.ui.h:26
++msgid "Installing the upgrades"
++msgstr "安裝升級"
++
++#: ../DistUpgrade/DistUpgradeView.py:263 ../DistUpgrade/DistUpgrade.ui.h:25
++msgid "Cleaning up"
++msgstr "清理"
++
++#: ../DistUpgrade/DistUpgradeView.py:348
++#, python-format
++msgid ""
++"%(amount)d installed package is no longer supported by Canonical. You can "
++"still get support from the community."
++msgid_plural ""
++"%(amount)d installed packages are no longer supported by Canonical. You can "
++"still get support from the community."
++msgstr[0] ""
++"已安裝套件中有 %(amount)d 個不再受 Canonical 支援。您仍可以取得來自社羣的支"
++"援。"
++
++#. FIXME: make those two separate lines to make it clear
++#. that the "%" applies to the result of ngettext
++#: ../DistUpgrade/DistUpgradeView.py:357
++#, python-format
++msgid "%d package is going to be removed."
++msgid_plural "%d packages are going to be removed."
++msgstr[0] "即將移除 %d 個套件。"
++
++#: ../DistUpgrade/DistUpgradeView.py:362
++#, python-format
++msgid "%d new package is going to be installed."
++msgid_plural "%d new packages are going to be installed."
++msgstr[0] "即將安裝 %d 個新套件。"
++
++#: ../DistUpgrade/DistUpgradeView.py:368
++#, python-format
++msgid "%d package is going to be upgraded."
++msgid_plural "%d packages are going to be upgraded."
++msgstr[0] "即將升級 %d 個套件。"
++
++#: ../DistUpgrade/DistUpgradeView.py:373
++#, python-format
++msgid ""
++"\n"
++"\n"
++"You have to download a total of %s. "
++msgstr ""
++"\n"
++"\n"
++"您必須下載全部的%s。 "
++
++#: ../DistUpgrade/DistUpgradeView.py:378
++msgid ""
++"Installing the upgrade can take several hours. Once the download has "
++"finished, the process cannot be canceled."
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeView.py:382
++msgid ""
++"Fetching and installing the upgrade can take several hours. Once the "
++"download has finished, the process cannot be canceled."
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeView.py:387
++msgid "Removing the packages can take several hours. "
++msgstr ""
++
++#. FIXME: this should go into DistUpgradeController
++#: ../DistUpgrade/DistUpgradeView.py:392 ../UpdateManager/UpdateManager.py:676
++msgid "The software on this computer is up to date."
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeView.py:393
++msgid ""
++"There are no upgrades available for your system. The upgrade will now be "
++"canceled."
++msgstr "您的系統已經在最新狀態。現在將取消升級的動作。"
++
++#: ../DistUpgrade/DistUpgradeView.py:406
++msgid "Reboot required"
++msgstr "需要重新開機"
++
++#: ../DistUpgrade/DistUpgradeView.py:407
++msgid ""
++"The upgrade is finished and a reboot is required. Do you want to do this now?"
++msgstr "升級已經完成及需要重新啟動。現在要重新啟動嗎?"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:72
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:72
++#, python-format
++msgid "authenticate '%(file)s' against '%(signature)s' "
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:131
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:131
++#, python-format
++msgid "extracting '%s'"
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:151
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:152
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:151
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:152
++msgid "Could not run the upgrade tool"
++msgstr "無法執行升級工具"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:152
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:152
++msgid ""
++"This is most likely a bug in the upgrade tool. Please report it as a bug "
++"using the command 'ubuntu-bug update-manager'."
++msgstr ""
++"這可能是升級工具的錯誤,請使用指令「ubuntu-bug update-manager」回報錯誤。"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:227
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:227
++msgid "Upgrade tool signature"
++msgstr "升級工具簽署"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:234
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:234
++msgid "Upgrade tool"
++msgstr "升級工具"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:268
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:268
++msgid "Failed to fetch"
++msgstr "提取失敗"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:269
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:269
++msgid "Fetching the upgrade failed. There may be a network problem. "
++msgstr "提取升級套件失敗。可能是網絡問題。 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:273
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:273
++msgid "Authentication failed"
++msgstr "認證失敗"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:274
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:274
++msgid ""
++"Authenticating the upgrade failed. There may be a problem with the network "
++"or with the server. "
++msgstr "認證升級套件失敗。可能是因為跟伺服器的網絡連線出現問題。 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:279
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:279
++msgid "Failed to extract"
++msgstr "解壓失敗"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:280
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:280
++msgid ""
++"Extracting the upgrade failed. There may be a problem with the network or "
++"with the server. "
++msgstr "升級套件解壓失敗。可能是因為網絡或伺服器出現問題。 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:285
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:285
++msgid "Verification failed"
++msgstr "驗證失敗"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:286
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:286
++msgid ""
++"Verifying the upgrade failed.  There may be a problem with the network or "
++"with the server. "
++msgstr "驗證升級套件失敗。可能是因為網絡或伺服器出現問題。 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:300
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:306
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:300
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:306
++msgid "Can not run the upgrade"
++msgstr "不能進行升級"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:301
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:301
++msgid ""
++"This usually is caused by a system where /tmp is mounted noexec. Please "
++"remount without noexec and run the upgrade again."
++msgstr ""
++"這通常是由使用 noexec 掛載 /tmp 的系統引致的。請不要使用 noexec 重新掛載,並"
++"再次進行升級。"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:307
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:307
++#, python-format
++msgid "The error message is '%s'."
++msgstr "錯誤訊息 '%s'。"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:93
++msgid ""
++"Please report this as a bug and include the files /var/log/dist-upgrade/main."
++"log and /var/log/dist-upgrade/apt.log in your report. The upgrade has "
++"aborted.\n"
++"Your original sources.list was saved in /etc/apt/sources.list.distUpgrade."
++msgstr ""
++"請回報此錯誤並將檔案 /var/log/dist-upgrade/main.log 與 /var/log/dist-upgrade/"
++"apt.log 附在報告。升級程序已中止。\n"
++"您原先的 sources.list 儲存於 /etc/apt/sources.list.distUpgrade"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:117
++msgid "Aborting"
++msgstr "正在中止"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:122
++msgid "Demoted:\n"
++msgstr "降等:\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:129
++msgid "To continue please press [ENTER]"
++msgstr "若要繼續請按 [ENTER]"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:157
++#: ../DistUpgrade/DistUpgradeViewText.py:196
++#: ../DistUpgrade/DistUpgradeViewText.py:203
++msgid "Continue [yN] "
++msgstr "繼續 [yN] "
++
++#: ../DistUpgrade/DistUpgradeViewText.py:157
++#: ../DistUpgrade/DistUpgradeViewText.py:196
++msgid "Details [d]"
++msgstr "詳情 [d]"
++
++#. TRANSLATORS: the "y" is "yes"
++#. TRANSLATORS: first letter of a positive (yes) answer
++#: ../DistUpgrade/DistUpgradeViewText.py:162
++#: ../DistUpgrade/DistUpgradeViewText.py:206
++msgid "y"
++msgstr "y"
++
++#. TRANSLATORS: the "n" is "no"
++#. TRANSLATORS: first letter of a negative (no) answer
++#: ../DistUpgrade/DistUpgradeViewText.py:165
++#: ../DistUpgrade/DistUpgradeViewText.py:213
++msgid "n"
++msgstr "n"
++
++#. TRANSLATORS: the "d" is "details"
++#: ../DistUpgrade/DistUpgradeViewText.py:168
++msgid "d"
++msgstr "d"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:173
++#, python-format
++msgid "No longer supported: %s\n"
++msgstr "不再支援:%s\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:178
++#, python-format
++msgid "Remove: %s\n"
++msgstr "移除: %s\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:188
++#, python-format
++msgid "Install: %s\n"
++msgstr "安裝: %s\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:193
++#, python-format
++msgid "Upgrade: %s\n"
++msgstr "升級: %s\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:210
++msgid "Continue [Yn] "
++msgstr "繼續 [Yn] "
++
++#: ../DistUpgrade/DistUpgradeViewText.py:231
++msgid ""
++"To finish the upgrade, a restart is required.\n"
++"If you select 'y' the system will be restarted."
++msgstr ""
++"需要重新開機才能完成更新。\n"
++"如果您選擇 'y' 系統將會重新開機。"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:1
++msgid "_Cancel Upgrade"
++msgstr "取消升級(_C)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:2
++msgid "_Resume Upgrade"
++msgstr "繼續升級(_R)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:3
++msgid ""
++"<b><big>Cancel the running upgrade?</big></b>\n"
++"\n"
++"The system could be in an unusable state if you cancel the upgrade. You are "
++"strongly adviced to resume the upgrade."
++msgstr ""
++"<b><big>取消正在執行的升級?</big></b>\n"
++"\n"
++"如果您取消升級可能會導致系統不穩定。強烈建議您繼續升級。"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:6
++msgid "_Start Upgrade"
++msgstr "開始升級(_S)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:9
++msgid "_Replace"
++msgstr "取代(_R)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:10
++msgid "Difference between the files"
++msgstr "檔案差異"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:11
++msgid "_Report Bug"
++msgstr "匯報錯誤(_R)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:12
++msgid "_Continue"
++msgstr "繼續(_C)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:13
++msgid "<b><big>Start the upgrade?</big></b>"
++msgstr "<b><big>開始升級嗎?</big></b>"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:15
++msgid ""
++"<b><big>Restart the system to complete the upgrade</big></b>\n"
++"\n"
++"Please save your work before continuing."
++msgstr ""
++"<b><big>重新啟動系統以完成更新</big></b>\n"
++"\n"
++"請在繼續前先儲存您的作業。"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:18
++msgid "Distribution Upgrade"
++msgstr "發行版升級"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:19
++#, fuzzy
++msgid "<b><big>Upgrading Ubuntu to version 12.10</big></b>"
++msgstr "<b><big>將 Ubuntu 升級至 11.10 版</big></b>"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:20
++msgid "    "
++msgstr "    "
++
++#: ../DistUpgrade/DistUpgrade.ui.h:22
++msgid "Setting new software channels"
++msgstr "設定新的軟件來源頻道"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:24
++msgid "Restarting the computer"
++msgstr "重新啟動系統"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:27
++msgid "Terminal"
++msgstr "終端"
++
++#: ../UpdateManager/backend/InstallBackendSynaptic.py:64
++msgid "Please wait, this can take some time."
++msgstr "請稍候,這可能需要一點時間。"
++
++#: ../UpdateManager/backend/InstallBackendSynaptic.py:66
++msgid "Update is complete"
++msgstr "更新完成"
++
++#: ../UpdateManager/DistUpgradeFetcher.py:114
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:109
++msgid "Could not find the release notes"
++msgstr "找不到發行公告"
++
++#: ../UpdateManager/DistUpgradeFetcher.py:115
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:110
++msgid "The server may be overloaded. "
++msgstr "伺服器可能負荷過重。 "
++
++#: ../UpdateManager/DistUpgradeFetcher.py:125
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:114
++msgid "Could not download the release notes"
++msgstr "無法下載發行公告"
++
++#: ../UpdateManager/DistUpgradeFetcher.py:126
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:115
++msgid "Please check your internet connection."
++msgstr "請檢查您的互聯網連線。"
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:68
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:91
++msgid "Upgrade"
++msgstr "升級"
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:95
++#: ../data/gtkbuilder/UpdateManager.ui.h:20
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:2
++msgid "Release Notes"
++msgstr "發行公告"
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:134
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:148
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:150
++msgid "Downloading additional package files..."
++msgstr "正在下載額外的套件檔案..."
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:148
++#, python-format
++msgid "File %s of %s at %sB/s"
++msgstr "檔案 %s / %s (速度:%sB/秒)"
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:150
++#, python-format
++msgid "File %s of %s"
++msgstr "檔案 %s / %s"
++
++#: ../UpdateManager/ChangelogViewer.py:75
++msgid "Open Link in Browser"
++msgstr "用瀏覽器開啟連結"
++
++#: ../UpdateManager/ChangelogViewer.py:78
++msgid "Copy Link to Clipboard"
++msgstr "複製連結至剪貼簿"
++
++#: ../UpdateManager/GtkProgress.py:162
++#, python-format
++msgid "Downloading file %(current)li of %(total)li with %(speed)s/s"
++msgstr "共 %(total)li 個檔案,正下載第 %(current)li 個 (速度:%(speed)s/秒)"
++
++#: ../UpdateManager/GtkProgress.py:167
++#, python-format
++msgid "Downloading file %(current)li of %(total)li"
++msgstr "共 %(total)li 個檔案,正下載第 %(current)li 個"
++
++#: ../UpdateManager/UpdateManager.py:106 ../do-release-upgrade:100
++msgid "Your Ubuntu release is not supported anymore."
++msgstr "您的 Ubuntu 發行版本已經不再支援。"
++
++#: ../UpdateManager/UpdateManager.py:107
++msgid ""
++"You will not get any further security fixes or critical updates. Please "
++"upgrade to a later version of Ubuntu."
++msgstr "將無法再取得保安修正或重要更新。請升級至最新版本 Ubuntu。"
++
++#: ../UpdateManager/UpdateManager.py:115
++msgid "Upgrade information"
++msgstr "升級資訊"
++
++#: ../UpdateManager/UpdateManager.py:233
++#: ../UpdateManagerText/UpdateManagerText.py:35
++msgid "Install"
++msgstr "安裝"
++
++#: ../UpdateManager/UpdateManager.py:235
++msgid "Name"
++msgstr ""
++
++#. upload_archive = version_match.group(2).strip()
++#: ../UpdateManager/UpdateManager.py:395
++#, python-format
++msgid "Version %s: \n"
++msgstr "版本 %s: \n"
++
++#: ../UpdateManager/UpdateManager.py:453
++msgid ""
++"No network connection detected, you can not download changelog information."
++msgstr "偵測不到網絡連線,故無法下載改動記錄。"
++
++#: ../UpdateManager/UpdateManager.py:463
++msgid "Downloading list of changes..."
++msgstr "正在下載改動清單..."
++
++#: ../UpdateManager/UpdateManager.py:507
++msgid "_Deselect All"
++msgstr "取消所有選取(_D)"
++
++#: ../UpdateManager/UpdateManager.py:513
++msgid "Select _All"
++msgstr "全部選取(_A)"
++
++#: ../UpdateManager/UpdateManager.py:572
++#, python-format
++msgid "%s will be downloaded."
++msgstr "會下載 %s。"
++
++#: ../UpdateManager/UpdateManager.py:584
++#, fuzzy
++msgid "The update has already been downloaded."
++msgid_plural "The updates have already been downloaded."
++msgstr[0] "更新已下載,但尚未安裝"
++
++#: ../UpdateManager/UpdateManager.py:589
++msgid "There are no updates to install."
++msgstr ""
++
++#: ../UpdateManager/UpdateManager.py:598
++msgid "Unknown download size."
++msgstr "下載大小不詳。"
++
++#: ../UpdateManager/UpdateManager.py:624
++msgid ""
++"It is unknown when the package information was updated last. Please click "
++"the 'Check' button to update the information."
++msgstr "未知套件資訊的上次更新時間。請點擊「檢查」按鈕來更新資訊。"
++
++#: ../UpdateManager/UpdateManager.py:630
++#, python-format
++msgid ""
++"The package information was last updated %(days_ago)s days ago.\n"
++"Press the 'Check' button below to check for new software updates."
++msgstr ""
++"%(days_ago)s 天前更新過套件資訊。\n"
++"請按下方「檢查」鈕看看有否新資訊。"
++
++#: ../UpdateManager/UpdateManager.py:635
++#, python-format
++msgid "The package information was last updated %(days_ago)s day ago."
++msgid_plural "The package information was last updated %(days_ago)s days ago."
++msgstr[0] "上次更新套件資訊是 %(days_ago)s 天前。"
++
++#: ../UpdateManager/UpdateManager.py:639
++#, python-format
++msgid "The package information was last updated %(hours_ago)s hour ago."
++msgid_plural ""
++"The package information was last updated %(hours_ago)s hours ago."
++msgstr[0] "上次更新套件資訊是 %(hours_ago)s 小時前。"
++
++#. TRANSLATORS: only in plural form, as %s minutes ago is one of 15, 30, 45 minutes ago
++#: ../UpdateManager/UpdateManager.py:644 ../UpdateManager/UpdateManager.py:646
++#: ../UpdateManager/UpdateManager.py:648
++#, python-format
++msgid "The package information was last updated about %s minutes ago."
++msgstr "套件資訊約 %s 分鐘前更新。"
++
++#: ../UpdateManager/UpdateManager.py:650
++msgid "The package information was just updated."
++msgstr "套件資訊剛更新。"
++
++#: ../UpdateManager/UpdateManager.py:689
++msgid "Software updates may be available for your computer."
++msgstr "可能有軟體更新提供予閣下之電腦。"
++
++#: ../UpdateManager/UpdateManager.py:697
++#, python-format
++msgid ""
++"Updated software has been issued since %s was released. Do you want to "
++"install it now?"
++msgstr ""
++
++#: ../UpdateManager/UpdateManager.py:700
++msgid ""
++"Updated software is available for this computer. Do you want to install it "
++"now?"
++msgstr ""
++
++#: ../UpdateManager/UpdateManager.py:758
++#, python-format
++msgid ""
++"The upgrade needs a total of %s free space on disk '%s'. Please free at "
++"least an additional %s of disk space on '%s'. Empty your trash and remove "
++"temporary packages of former installations using 'sudo apt-get clean'."
++msgstr ""
++"升級工作需要總共 %s 可用空間於硬碟 ‘%s’。請額外空出最少 %s 的空間於 ‘%s’。清"
++"理清理您的回收筒或使用 ‘sudo apt-get clean’ 移除上次安裝的暫存套件。"
++
++#: ../UpdateManager/UpdateManager.py:783
++msgid ""
++"The computer needs to restart to finish installing updates. Please save your "
++"work before continuing."
++msgstr "必須重新啟動電腦來完成安裝更新,在繼續之前請先儲存您的工作。"
++
++#: ../UpdateManager/UpdateManager.py:847
++msgid "Reading package information"
++msgstr "正在讀取套件資訊"
++
++#: ../UpdateManager/UpdateManager.py:862
++msgid "Connecting..."
++msgstr "連線中..."
++
++#: ../UpdateManager/UpdateManager.py:879
++msgid "You may not be able to check for updates or download new updates."
++msgstr "可能無法檢查是否有、或下載新的更新。"
++
++#: ../UpdateManager/UpdateManager.py:1002
++msgid "Could not initialize the package information"
++msgstr "無法為套件資訊進行初始化"
++
++#: ../UpdateManager/UpdateManager.py:1003
++msgid ""
++"An unresolvable problem occurred while initializing the package "
++"information.\n"
++"\n"
++"Please report this bug against the 'update-manager' package and include the "
++"following error message:\n"
++msgstr ""
++"為套件資訊進行初始化時發生不能解決的問題。\n"
++"\n"
++"請將此匯報為「update-manager」套件的問題並附上以下錯誤訊息:\n"
++
++#: ../UpdateManager/UpdateManager.py:1032
++msgid ""
++"An unresolvable problem occurred while calculating the upgrade.\n"
++"\n"
++"Please report this bug against the 'update-manager' package and include the "
++"following error message:"
++msgstr ""
++"為升級進行推算時有問題無法解決。\n"
++"\n"
++"請為「update-manager」套件匯報此問題並附上以下錯誤訊息:"
++
++#: ../UpdateManager/UpdateManager.py:1056
++msgid " (New install)"
++msgstr " (新安裝)"
++
++#. TRANSLATORS: the b stands for Bytes
++#: ../UpdateManager/UpdateManager.py:1063
++#, python-format
++msgid "(Size: %s)"
++msgstr "(大小:%s)"
++
++#: ../UpdateManager/UpdateManager.py:1067
++#, python-format
++msgid "From version %(old_version)s to %(new_version)s"
++msgstr "由 %(old_version)s 版更新至 %(new_version)s 版"
++
++#: ../UpdateManager/UpdateManager.py:1071
++#, python-format
++msgid "Version %s"
++msgstr "%s 版"
++
++#: ../UpdateManager/UpdateManager.py:1104 ../do-release-upgrade:112
++msgid "Release upgrade not possible right now"
++msgstr "目前不能升級發行版"
++
++#: ../UpdateManager/UpdateManager.py:1105 ../do-release-upgrade:113
++#, c-format, python-format
++msgid ""
++"The release upgrade can not be performed currently, please try again later. "
++"The server reported: '%s'"
++msgstr "目前無法升級發行版,請稍後重試。該伺服器回報:「%s」。"
++
++#: ../UpdateManager/UpdateManager.py:1107 ../check-new-release-gtk:126
++msgid "Downloading the release upgrade tool"
++msgstr "正在下載發行版更新工具"
++
++#: ../UpdateManager/UpdateManager.py:1114
++#, python-format
++msgid "<b>New Ubuntu release '%s' is available</b>"
++msgstr "<b>有新的 Ubuntu 發行版 '%s' 可供升級</b>"
++
++#. we assert a clean cache
++#: ../UpdateManager/UpdateManager.py:1153
++msgid "Software index is broken"
++msgstr "軟件索引已損壞"
++
++#: ../UpdateManager/UpdateManager.py:1154
++msgid ""
++"It is impossible to install or remove any software. Please use the package "
++"manager \"Synaptic\" or run \"sudo apt-get install -f\" in a terminal to fix "
++"this issue at first."
++msgstr ""
++"無法安裝或移除套件。請先以「Synaptic 套件管理員」或在終端機執行「sudo apt-"
++"get install -f」修正問題。"
++
++#: ../UpdateManager/UnitySupport.py:57
++msgid "Check for Updates"
++msgstr "檢查有否更新"
++
++#: ../UpdateManager/UnitySupport.py:66
++msgid "Install All Available Updates"
++msgstr "安裝所有可進行的更新"
++
++#: ../UpdateManagerText/UpdateManagerText.py:34
++msgid "Cancel"
++msgstr "取消"
++
++#: ../UpdateManagerText/UpdateManagerText.py:37
++msgid "Changelog"
++msgstr ""
++
++#: ../UpdateManagerText/UpdateManagerText.py:40
++msgid "Updates"
++msgstr ""
++
++#: ../UpdateManagerText/UpdateManagerText.py:53
++msgid "Building Updates List"
++msgstr "正在建立更新清單"
++
++#: ../UpdateManagerText/UpdateManagerText.py:56
++msgid ""
++"\n"
++"A normal upgrade can not be calculated, please run: \n"
++"  sudo apt-get dist-upgrade\n"
++"\n"
++"\n"
++"This can be caused by:\n"
++" * A previous upgrade which didn't complete\n"
++" * Problems with some of the installed software\n"
++" * Unofficial software packages not provided by Ubuntu\n"
++" * Normal changes of a pre-release version of Ubuntu"
++msgstr ""
++"\n"
++"無法為標準升級進行推算,請執行:\n"
++"  sudo apt-get dist-upgrade\n"
++"\n"
++"\n"
++" 原因可能是:\n"
++" * 前次升級程序未完成\n"
++" * 某些已安裝的軟件有問題\n"
++" * 非 Ubuntu 官方軟件套件的問題\n"
++" * 測試版 Ubuntu 的正常改動"
++
++#: ../UpdateManagerText/UpdateManagerText.py:125
++msgid "Downloading changelog"
++msgstr "正在下載改動記錄"
++
++#: ../UpdateManager/Core/MyCache.py:147
++#, python-format
++msgid "Other updates (%s)"
++msgstr "其他更新 (%s)"
++
++#: ../UpdateManager/Core/MyCache.py:325
++msgid "This update does not come from a source that supports changelogs."
++msgstr "此更新來源不支援改動記錄。"
++
++#: ../UpdateManager/Core/MyCache.py:331 ../UpdateManager/Core/MyCache.py:359
++msgid ""
++"Failed to download the list of changes. \n"
++"Please check your Internet connection."
++msgstr ""
++"未能下載改動清單。\n"
++"請檢查互聯網連線。"
++
++#: ../UpdateManager/Core/MyCache.py:338
++#, python-format
++msgid ""
++"Changes for the versions:\n"
++"Installed version: %s\n"
++"Available version: %s\n"
++"\n"
++msgstr ""
++"版本改動:\n"
++"已安裝版本:%s\n"
++"新版本:%s\n"
++"\n"
++
++#: ../UpdateManager/Core/MyCache.py:348
++#, python-format
++msgid ""
++"The changelog does not contain any relevant changes.\n"
++"\n"
++"Please use http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n"
++"until the changes become available or try again later."
++msgstr ""
++"改動記錄並未包含相關資料。\n"
++"\n"
++"有改動紀錄提供前請看 http://launchpad.net/ubuntu/+source/%s/%s/"
++"+changelog ,\n"
++"或稍候再嘗試。"
++
++#: ../UpdateManager/Core/MyCache.py:353
++#, python-format
++msgid ""
++"The list of changes is not available yet.\n"
++"\n"
++"Please use http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n"
++"until the changes become available or try again later."
++msgstr ""
++"仍未有改動清單提供。\n"
++"\n"
++"有改動清單提供前請看 http://launchpad.net/ubuntu/+source/%s/%s/"
++"+changelog ,\n"
++"或稍候再嘗試。"
++
++#: ../UpdateManager/Core/UpdateList.py:51
++msgid "Failed to detect distribution"
++msgstr "無法偵測出版本"
++
++#: ../UpdateManager/Core/UpdateList.py:52
++#, python-format
++msgid "A error '%s' occurred while checking what system you are using."
++msgstr "當檢查您所使用的系統時有錯誤 \"%s\" 發生。"
++
++#: ../UpdateManager/Core/UpdateList.py:63
++msgid "Important security updates"
++msgstr "重要保安更新"
++
++#: ../UpdateManager/Core/UpdateList.py:64
++msgid "Recommended updates"
++msgstr "重要更新"
++
++#: ../UpdateManager/Core/UpdateList.py:65
++msgid "Proposed updates"
++msgstr "建議更新"
++
++#: ../UpdateManager/Core/UpdateList.py:66
++msgid "Backports"
++msgstr "回植套件"
++
++#: ../UpdateManager/Core/UpdateList.py:67
++msgid "Distribution updates"
++msgstr "發行版更新"
++
++#: ../UpdateManager/Core/UpdateList.py:72
++msgid "Other updates"
++msgstr "其他更新"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:1
++#, fuzzy
++msgid "<big><b>Starting Software Updater</b></big>"
++msgstr "<big><b>啟動更新管理員</b></big>"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:2
++msgid ""
++"Software updates correct errors, eliminate security vulnerabilities and "
++"provide new features."
++msgstr "軟件更新會更正錯誤、排除安全隱患並提供新功能。"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:3
++msgid "_Partial Upgrade"
++msgstr "部份升級(_P)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:4
++msgid "<big><b>Not all updates can be installed</b></big>"
++msgstr "<big><b>並非所有更新都可以安裝</b></big>"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:5
++msgid ""
++"Run a partial upgrade, to install as many updates as possible. \n"
++"\n"
++"This can be caused by:\n"
++" * A previous upgrade which didn't complete\n"
++" * Problems with some of the installed software\n"
++" * Unofficial software packages not provided by Ubuntu\n"
++" * Normal changes of a pre-release version of Ubuntu"
++msgstr ""
++"執行部份升級,會儘可能安裝最多更新。 \n"
++"\n"
++"原因可能是:\n"
++" * 前次升級程序未完成\n"
++" * 某些已安裝的軟件有問題\n"
++" * 非 Ubuntu 官方軟件套件的問題\n"
++" * 測試版 Ubuntu 的正常改動"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:12
++msgid "Chec_k"
++msgstr "檢查(_K)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:13
++msgid ""
++"<b><big>You must check for updates manually</big></b>\n"
++"\n"
++"Your system does not check for updates automatically. You can configure this "
++"behavior in <i>Software Sources</i> on the <i>Updates</i> tab."
++msgstr ""
++"<b><big>必須手動檢查更新</big></b>\n"
++"\n"
++"系統不會自動檢查更新。可在<i>更新</i> 分頁的<i>軟件來源</i> 設定。"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:16
++msgid "_Hide this information in the future"
++msgstr "以後不要再顯示此訊息(_H)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:17
++msgid "Co_ntinue"
++msgstr "繼續(_N)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:18
++msgid "<big><b>Running on battery</b></big>"
++msgstr "<big><b>使用電池運行</b></big>"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:19
++msgid "Your system is running on battery. Are you sure you want to continue?"
++msgstr "您的系統正在使用電池。確定要繼續嗎?"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:21
++msgid "_Upgrade"
++msgstr "升級(_U)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:22
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:8
++msgid "Show progress of individual files"
++msgstr "顯示個別檔案進度"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:23
++#: ../data/update-manager.desktop.in.h:1
++#, fuzzy
++msgid "Software Updater"
++msgstr "軟件更新"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:24
++#, fuzzy
++msgid "Starting Software Updater"
++msgstr "軟件更新"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:25
++msgid "U_pgrade"
++msgstr "升級(_P)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:27
++msgid "updates"
++msgstr "更新"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:28
++msgid "Changes"
++msgstr "改動"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:29
++msgid "Description"
++msgstr "說明"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:30
++#, fuzzy
++msgid "Details of updates"
++msgstr "更新說明"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:31
++msgid ""
++"You are connected via roaming and may be charged for the data consumed by "
++"this update."
++msgstr "正以漫遊連上網絡,可能要對本次更新所下載的資料量付費。"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:32
++msgid ""
++"You may want to wait until you’re not using a mobile broadband connection."
++msgstr ""
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:33
++msgid "It’s safer to connect the computer to AC power before updating."
++msgstr "在更新前先將電腦接上變壓器比較安全。"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:34
++msgid "_Settings..."
++msgstr "設定(_S)..."
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:35
++#, fuzzy
++msgid "_Install Now"
++msgstr "安裝"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:1
++msgid "<b>A new version of Ubuntu is available. Would you like to upgrade?</b>"
++msgstr "<b>有新版本 Ubuntu。是否升級?</b>"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:3
++msgid "Don't Upgrade"
++msgstr "不升級"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:4
++msgid "Ask Me Later"
++msgstr "稍後再問我"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:5
++msgid "Yes, Upgrade Now"
++msgstr "是,現在升級"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:6
++msgid "You have declined to upgrade to the new Ubuntu"
++msgstr "您已拒絕升級至新版 Ubuntu"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:7
++#, fuzzy
++msgid ""
++"You can upgrade at a later time by opening Software Updater and click on "
++"\"Upgrade\"."
++msgstr "您稍後仍可以透過開啟更新管理員並按下『升級』進行升級。"
++
++#: ../data/update-manager.desktop.in.h:2
++msgid "Software Updates"
++msgstr "軟件更新"
++
++#: ../data/update-manager.desktop.in.h:3
++msgid "Show and install available updates"
++msgstr "顯示並安裝現有的軟件更新"
++
++#: ../update-manager:66 ../update-manager-text:55 ../do-release-upgrade:51
++msgid "Show version and exit"
++msgstr "顯示版本並結束"
++
++#: ../update-manager:69
++msgid "Directory that contains the data files"
++msgstr "含有資料檔案的目錄"
++
++#: ../update-manager:72
++msgid "Check if a new Ubuntu release is available"
++msgstr "檢查有否新 Ubuntu 發行版可供升級"
++
++#: ../update-manager:75 ../do-release-upgrade:54 ../check-new-release-gtk:186
++msgid "Check if upgrading to the latest devel release is possible"
++msgstr "檢查能否升級至最新測試版"
++
++#: ../update-manager:79
++msgid "Upgrade using the latest proposed version of the release upgrader"
++msgstr "以最新建議版本的發行升級工具進行升級"
++
++#: ../update-manager:86
++msgid "Do not focus on map when starting"
++msgstr "啟動時不預先選取圖錄"
++
++#: ../update-manager:89
++msgid "Try to run a dist-upgrade"
++msgstr "試著執行 dist-upgrade"
++
++#: ../update-manager:92
++msgid "Do not check for updates when starting"
++msgstr "啟動時不要檢查更新"
++
++#: ../update-manager:96 ../do-release-upgrade:70
++msgid "Test upgrade with a sandbox aufs overlay"
++msgstr "使用沙堆 aufs 層測試升級"
++
++#: ../update-manager:116
++msgid "Running partial upgrade"
++msgstr "執行部份升級"
++
++#: ../update-manager-text:59
++msgid "Show description of the package instead of the changelog"
++msgstr ""
++
++#: ../do-release-upgrade:58 ../check-new-release-gtk:190
++msgid ""
++"Try upgrading to the latest release using the upgrader from $distro-proposed"
++msgstr "嘗試使用 $distro-proposed 的升級程式來升級至最新的發行版本"
++
++#: ../do-release-upgrade:62
++msgid ""
++"Run in a special upgrade mode.\n"
++"Currently 'desktop' for regular upgrades of a desktop system and 'server' "
++"for server systems are supported."
++msgstr ""
++"以特殊升級模式進行。\n"
++"目前只支援以 'desktop' 模式升級桌面版本的系統,以及以 'server' 模式升級伺服器"
++"版的系統。"
++
++#: ../do-release-upgrade:68
++msgid "Run the specified frontend"
++msgstr "執行指定的前端"
++
++#: ../do-release-upgrade:73
++msgid ""
++"Check only if a new distribution release is available and report the result "
++"via the exit code"
++msgstr "檢查是否有新的發行版並以結束碼報告結果"
++
++#: ../do-release-upgrade:87
++msgid "Checking for a new Ubuntu release"
++msgstr ""
++
++#: ../do-release-upgrade:101
++msgid ""
++"For upgrade information, please visit:\n"
++"%(url)s\n"
++msgstr ""
++"若要取得升級資訊,請參訪:\n"
++"%(url)s\n"
++
++#: ../do-release-upgrade:107
++msgid "No new release found"
++msgstr "找不到新發行版"
++
++#: ../do-release-upgrade:119
++#, c-format
++msgid "New release '%s' available."
++msgstr "有新發行版 '%s' 提供。"
++
++#: ../do-release-upgrade:120
++msgid "Run 'do-release-upgrade' to upgrade to it."
++msgstr "執行 ‘do-release-upgrade’ 進行升級工作。"
++
++#: ../check-new-release-gtk:101
++msgid "Ubuntu %(version)s Upgrade Available"
++msgstr "可以升級至 Ubuntu %(version)s"
++
++#: ../check-new-release-gtk:143
++#, c-format
++msgid "You have declined the upgrade to Ubuntu %s"
++msgstr "您已拒絕升級至 Ubuntu %s"
++
++#: ../check-new-release-gtk:196
++msgid "Add debug output"
++msgstr ""
++
++#: ../ubuntu-support-status:91
++msgid "Show unsupported packages on this machine"
++msgstr ""
++
++#: ../ubuntu-support-status:94
++msgid "Show supported packages on this machine"
++msgstr ""
++
++#: ../ubuntu-support-status:97
++msgid "Show all packages with their status"
++msgstr ""
++
++#: ../ubuntu-support-status:100
++msgid "Show all packages in a list"
++msgstr ""
++
++#: ../ubuntu-support-status:142
++#, c-format
++msgid "Support status summary of '%s':"
++msgstr ""
++
++#: ../ubuntu-support-status:145
++msgid "You have %(num)s packages (%(percent).1f%%) supported until %(time)s"
++msgstr ""
++
++#: ../ubuntu-support-status:151
++msgid ""
++"You have %(num)s packages (%(percent).1f%%) that can not/no-longer be "
++"downloaded"
++msgstr ""
++
++#: ../ubuntu-support-status:154
++msgid "You have %(num)s packages (%(percent).1f%%) that are unsupported"
++msgstr ""
++
++#: ../ubuntu-support-status:162
++msgid ""
++"Run with --show-unsupported, --show-supported or --show-all to see more "
++"details"
++msgstr ""
++
++#: ../ubuntu-support-status:166
++msgid "No longer downloadable:"
++msgstr ""
++
++#: ../ubuntu-support-status:169
++msgid "Unsupported: "
++msgstr ""
++
++#: ../ubuntu-support-status:174
++#, c-format
++msgid "Supported until %s:"
++msgstr ""
++
++#: ../ubuntu-support-status:183
++msgid "Unsupported"
++msgstr ""
++
++#. Why do we use %s here instead of $strings or {} format placeholders?
++#. It's because we don't want to break existing translations.
++#: ../janitor/plugincore/exceptions.py:42
++#, python-format
++msgid "Unimplemented method: %s"
++msgstr "未實作的方法: %s"
++
++#: ../janitor/plugincore/core/file_cruft.py:41
++msgid "A file on disk"
++msgstr "磁碟上之檔案"
++
++#: ../janitor/plugincore/core/missing_package_cruft.py:39
++msgid "Install missing package."
++msgstr "安裝缺少的套件。"
++
++#. 2012-06-08 BAW: i18n string; don't use {} or PEP 292.
++#: ../janitor/plugincore/core/missing_package_cruft.py:49
++#, python-format
++msgid "Package %s should be installed."
++msgstr "應安裝 %s 套件。"
++
++#: ../janitor/plugincore/core/package_cruft.py:49
++msgid ".deb package"
++msgstr ".deb 套件"
++
++#: ../janitor/plugincore/plugins/langpack_manual_plugin.py:46
++#, python-format
++msgid "%s needs to be marked as manually installed."
++msgstr "%s 要標記為手動安裝。"
++
++#: ../janitor/plugincore/plugins/kdelibs4to5_plugin.py:49
++msgid ""
++"When upgrading, if kdelibs4-dev is installed, kdelibs5-dev needs to be "
++"installed. See bugs.launchpad.net, bug #279621 for details."
++msgstr ""
++"升級時如已安裝 kdelibs4-dev,那就必須安裝 kdelibs5-dev。詳情請見 bugs."
++"launchpad.net,bug #279621。"
++
++#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:44
++#, python-format
++msgid "%i obsolete entries in the status file"
++msgstr "狀態檔中有 %i 條廢棄項目"
++
++#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:47
++msgid "Obsolete entries in dpkg status"
++msgstr "dpkg 狀態中有廢棄條目"
++
++#. pragma: no cover
++#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:50
++msgid "Obsolete dpkg status entries"
++msgstr "廢棄的 dpkg 狀態項目"
++
++#: ../janitor/plugincore/plugins/remove_lilo_plugin.py:42
++msgid "Remove lilo since grub is also installed.(See bug #314004 for details.)"
++msgstr "因 grub 已安裝,移除 lilo  (詳情見 bug #314004)"
++
++#~ msgid "<b><big>Upgrading Ubuntu to version 12.04</big></b>"
++#~ msgstr "<b><big>將 Ubuntu 升級至 12.04 版</big></b>"
++
++#~ msgid "%(count)s update has been selected."
++#~ msgid_plural "%(count)s updates have been selected."
++#~ msgstr[0] "已選取 %(count)s 項更新。"
++
++#~ msgid "%(count_str)s %(download_str)s"
++#~ msgstr "%(count_str)s %(download_str)s"
++
++#~ msgid "Welcome to Ubuntu"
++#~ msgstr "歡迎使用 Ubuntu"
++
++#~ msgid "Update Manager"
++#~ msgstr "更新管理員"
++
++#~ msgid "Starting Update Manager"
++#~ msgstr "正在啟動更新管理員"
++
++#~ msgid "You are connected via a wireless modem."
++#~ msgstr "您正以無線數據機連線。"
++
++#~ msgid "_Install Updates"
++#~ msgstr "安裝更新套件(_I)"
++
++#~ msgid "Your system is up-to-date"
++#~ msgstr "系統已經在最新狀態"
++
++#~ msgid "Software updates are available for this computer"
++#~ msgstr "有軟件更新適用於此電腦"
++
++#~ msgid "There are no updates to install"
++#~ msgstr "沒有要安裝的升級"
++
++#~ msgid "%.0f kB"
++#~ msgstr "%.0f kB"
++
++#~ msgid "0 kB"
++#~ msgstr "0 kB"
++
++#~ msgid ""
++#~ "\n"
++#~ "\n"
++#~ "Please report this bug using the command 'ubuntu-bug update-manager' in a "
++#~ "terminal and include the files in /var/log/dist-upgrade/ in the bug "
++#~ "report.\n"
++#~ "%s"
++#~ msgstr ""
++#~ "\n"
++#~ "\n"
++#~ "請在終端機內輸入指令「ubuntu-bug update-manager」回報錯誤,並在錯誤報告中"
++#~ "附上 /var/log/dist-upgrade/ 內之檔案。\n"
++#~ "%s"
++
++#~ msgid ""
++#~ "Preparing the system for the upgrade failed. Please report this using the "
++#~ "command 'ubuntu-bug update-manager' in a terminal and include the files "
++#~ "in /var/log/dist-upgrade/ in the bug report."
++#~ msgstr ""
++#~ "準備系統升級失敗。請在終端機內輸入指令「ubuntu-bug update-manager」回報錯"
++#~ "誤,並在錯誤報告中附上 /var/log/dist-upgrade/ 內之檔案。"
++
++#~ msgid ""
++#~ "Upgrading the repository information resulted in a invalid file. Please "
++#~ "report this as a bug using the command 'ubuntu-bug update-manager' in a "
++#~ "terminal."
++#~ msgstr ""
++#~ "升級套件庫時導致無效的檔案。請在終端機內輸入指令「ubuntu-bug update-"
++#~ "manager」回報錯誤。"
++
++#~ msgid "1 kB"
++#~ msgstr "1 kB"
++
++#~ msgid "Your graphics hardware may not be fully supported in Ubuntu 11.04."
++#~ msgstr "您的繪圖硬件可能無法在 Ubuntu 11.04 獲得完整的支援。"
++
++#~ msgid ""
++#~ "The support in Ubuntu 11.04 for your intel graphics hardware is limited "
++#~ "and you may encounter problems after the upgrade. Do you want to continue "
++#~ "with the upgrade?"
++#~ msgstr ""
++#~ "您的 Intel 繪圖硬件在 Ubuntu 11.04 內的支援有限,且可能會在升級之後碰到一"
++#~ "些問題。您要繼續進行升級嗎?"
++
++#~ msgid ""
++#~ "The system was unable to get the prerequisites for the upgrade. The "
++#~ "upgrade will abort now and restore the original system state.\n"
++#~ "\n"
++#~ "Please report this as a bug using the command 'ubuntu-bug update-manager' "
++#~ "in a terminal and include the files in /var/log/dist-upgrade/ in the bug "
++#~ "report."
++#~ msgstr ""
++#~ "此系統無法達到升級之要求。現在將中斷升級並將系統回復至原來狀態。\n"
++#~ "\n"
++#~ "請在終端機內輸入指令「ubuntu-bug update-manager」回報錯誤,並在錯誤報告中"
++#~ "附上 /var/log/dist-upgrade/ 內之檔案。"
++
++#~ msgid ""
++#~ "After your package information was updated the essential package '%s' can "
++#~ "not be found anymore.\n"
++#~ "This indicates a serious error, please report this bug using the command "
++#~ "'ubuntu-bug update-manager' in a terminal and include the files in /var/"
++#~ "log/dist-upgrade/ in the bug report."
++#~ msgstr ""
++#~ "更新套件資訊後再找不到必備套件「%s」。\n"
++#~ "此為嚴重錯誤,請在終端機內輸入指令「ubuntu-bug update-manager」回報錯誤,"
++#~ "並在錯誤報告附上 /var/log/dist-upgrade/ 內的檔案。"
++
++#~ msgid ""
++#~ "You will not get any further security fixes or critical updates. Please "
++#~ "upgrade to a later version of Ubuntu Linux."
++#~ msgstr "無法再取得保安修正與重大更新。請升級至新版 Ubuntu Linux。"
++
++#~ msgid ""
++#~ "If you don't want to install them now, choose \"Update Manager\" from "
++#~ "Applications later."
++#~ msgstr "若現在不想安裝,可稍後於「應用程式」選單開啟「更新管理員」再安裝。"
++
++#~ msgid ""
++#~ "These software updates have been issued since this version of Ubuntu was "
++#~ "released. If you don't want to install them now, choose \"Update Manager"
++#~ "\" from Applications later."
++#~ msgstr ""
++#~ "本 Ubuntu 版本自發行已發布此等軟件更新。若現在不想安裝,可稍後於「應用程"
++#~ "式」選單開啟「更新管理員」再安裝。"
++
++#~ msgid ""
++#~ "These software updates have been issued since this version of Ubuntu was "
++#~ "released. If you don't want to install them now, choose \"Update Manager"
++#~ "\" from the Administration Menu later."
++#~ msgstr ""
++#~ "本 Ubuntu 版本自發行已發布此等軟件更新。若現在不想安裝,可稍後於「管理」選"
++#~ "單開啟「更新管理員」再安裝。"
++
++#~ msgid ""
++#~ "If you don't want to install them now, choose \"Update Manager\" from the "
++#~ "Administration menu later."
++#~ msgstr "若現在不想安裝,可稍後於「管理」選單開啟「更新管理員」再安裝。"
++
++#~ msgid ""
++#~ "This upgrade is running in sandbox (test) mode. All changes are written "
++#~ "to '%s' and will be lost on the next reboot.\n"
++#~ "\n"
++#~ "*No* changes written to a systemdir from now until the next reboot are "
++#~ "permanent."
++#~ msgstr ""
++#~ "這次升級是在沙堆 (測試) 模式執行。所有改動都會寫入至「%s」並在下次重新開機"
++#~ "時消失。\n"
++#~ "\n"
++#~ "由現在起至下次重新開機,寫入至系統目錄之改動都*不會*保留。"
++
++#~ msgid "Checking for a new ubuntu release"
++#~ msgstr "檢查有否新 Ubuntu 發行版"
++
++#~ msgid ""
++#~ "Fetching and installing the upgrade can take several hours. Once the "
++#~ "download has finished, the process cannot be cancelled."
++#~ msgstr "提取檔案及安裝升級可能要花數小時。一旦下載完成即不能取消升級程序。"
++
++
++msgid "Unable to access the source management server, 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 "其他任務正在更新升級中,請稍後再卸載。"
++
++#: ../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 "Application installation control policy not enabled ."
++msgstr "應用安裝管控未開啓."
++
++msgid "Installation failed! Application is not in the software whitelist list!"
++msgstr "安裝失敗!軟件包不在白名單列表!"
++
++msgid "Installation failed! Application is in the software blacklist list!"
++msgstr "安裝失敗!軟件包在黑名單列表!"
++
++msgid "Application installation in unknown mode ."
++msgstr "應用安裝管控策略未知."
++
++#: ../SystemUpdater/Core/utils.py:753
++msgid "Cancel authentication."
++msgstr "取消認證"
+diff --git a/backend-immutable/tests/po/zh_TW.po b/backend-immutable/tests/po/zh_TW.po
+new file mode 100644
+index 0000000..412d059
+--- /dev/null
++++ b/backend-immutable/tests/po/zh_TW.po
+@@ -0,0 +1,2744 @@
++msgid ""
++msgstr ""
++"Project-Id-Version: update-manager 0.41.1\n"
++"Report-Msgid-Bugs-To: sebastian.heinlein@web.de\n"
++"POT-Creation-Date: 2012-06-14 00:53+0100\n"
++"PO-Revision-Date: 2012-03-23 02:57+0000\n"
++"Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"
++"Language-Team: Chinese (Taiwan) <zh-l10n@linux.org.tw>\n"
++"Language: \n"
++"MIME-Version: 1.0\n"
++"Content-Type: text/plain; charset=UTF-8\n"
++"Content-Transfer-Encoding: 8bit\n"
++"Plural-Forms: nplurals=1; plural=0;\n"
++"X-Launchpad-Export-Date: 2012-04-17 13:41+0000\n"
++"X-Generator: Launchpad (build 15099)\n"
++
++#. TRANSLATORS: download size of small updates, e.g. "250 kB"
++#: ../DistUpgrade/utils.py:433 ../UpdateManager/Core/utils.py:433
++#, python-format
++msgid "%(size).0f kB"
++msgid_plural "%(size).0f kB"
++msgstr[0] "%(size).0f kB"
++
++#. TRANSLATORS: download size of updates, e.g. "2.3 MB"
++#: ../DistUpgrade/utils.py:436 ../UpdateManager/Core/utils.py:436
++#, python-format
++msgid "%.1f MB"
++msgstr "%.1f MB"
++
++#. TRANSLATORS: %s is a country
++#: ../DistUpgrade/distro.py:206 ../DistUpgrade/distro.py:436
++#, python-format
++msgid "Server for %s"
++msgstr "%s伺服器"
++
++#. More than one server is used. Since we don't handle this case
++#. in the user interface we set "custom servers" to true and
++#. append a list of all used servers
++#: ../DistUpgrade/distro.py:224 ../DistUpgrade/distro.py:230
++#: ../DistUpgrade/distro.py:246
++msgid "Main server"
++msgstr "主伺服器"
++
++#: ../DistUpgrade/distro.py:250
++msgid "Custom servers"
++msgstr "自訂伺服器"
++
++#: ../DistUpgrade/DistUpgradeAptCdrom.py:142
++msgid "Could not calculate sources.list entry"
++msgstr "無法計算 sources.list 項目"
++
++#: ../DistUpgrade/DistUpgradeAptCdrom.py:251
++msgid ""
++"Unable to locate any package files, perhaps this is not a Ubuntu Disc or the "
++"wrong architecture?"
++msgstr "找不到套件檔,也許這不是 Ubuntu 光碟,或者處理器架構不對。"
++
++#: ../DistUpgrade/DistUpgradeAptCdrom.py:294
++msgid "Failed to add the CD"
++msgstr "無法加入光碟"
++
++#: ../DistUpgrade/DistUpgradeAptCdrom.py:295
++#, python-format
++msgid ""
++"There was a error adding the CD, the upgrade will abort. Please report this "
++"as a bug if this is a valid Ubuntu CD.\n"
++"\n"
++"The error message was:\n"
++"'%s'"
++msgstr ""
++"加入光碟時發生錯誤,升級將終止。若您確定光碟沒有問題,請將此匯報為臭蟲。\n"
++"\n"
++"錯誤訊息:\n"
++"「%s」"
++
++#: ../DistUpgrade/DistUpgradeCache.py:151
++msgid "Remove package in bad state"
++msgid_plural "Remove packages in bad state"
++msgstr[0] "移除有問題套件"
++
++#: ../DistUpgrade/DistUpgradeCache.py:154
++#, python-format
++msgid ""
++"The package '%s' is in an inconsistent state and needs to be reinstalled, "
++"but no archive can be found for it. Do you want to remove this package now "
++"to continue?"
++msgid_plural ""
++"The packages '%s' are in an inconsistent state and need to be reinstalled, "
++"but no archives can be found for them. Do you want to remove these packages "
++"now to continue?"
++msgstr[0] ""
++"「%s」套件狀態不一致而需要重新安裝,但找不到其存檔。是否移除此套件並繼續?"
++
++#. FIXME: not ideal error message, but we just reuse a
++#. existing one here to avoid a new string
++#: ../DistUpgrade/DistUpgradeCache.py:255
++msgid "The server may be overloaded"
++msgstr "伺服器可能負載過大"
++
++#: ../DistUpgrade/DistUpgradeCache.py:368
++msgid "Broken packages"
++msgstr "損毀套件"
++
++#: ../DistUpgrade/DistUpgradeCache.py:369
++msgid ""
++"Your system contains broken packages that couldn't be fixed with this "
++"software. Please fix them first using synaptic or apt-get before proceeding."
++msgstr ""
++"本軟體無法修正閣下系統某有損毀套件。請先使用 synaptic 或 apt-get 修正才繼續。"
++
++#. FIXME: change the text to something more useful
++#: ../DistUpgrade/DistUpgradeCache.py:693
++#, python-format
++msgid ""
++"An unresolvable problem occurred while calculating the upgrade:\n"
++"%s\n"
++"\n"
++" This can be caused by:\n"
++" * Upgrading to a pre-release version of Ubuntu\n"
++" * Running the current pre-release version of Ubuntu\n"
++" * Unofficial software packages not provided by Ubuntu\n"
++"\n"
++msgstr ""
++"準備升級時發生不能解決的問題:\n"
++"%s\n"
++"\n"
++" 這可能由以下原因造成:\n"
++" * 正升級至非正式發佈版本的 Ubuntu\n"
++" * 正使用非正式發佈版本的 Ubuntu\n"
++" * 安裝了非由 Ubuntu 官方提供的軟體套件\n"
++"\n"
++
++#: ../DistUpgrade/DistUpgradeCache.py:703
++msgid "This is most likely a transient problem, please try again later."
++msgstr "很可能只是暫時有問題。請稍候再試。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:706
++msgid ""
++"If none of this applies, then please report this bug using the command "
++"'ubuntu-bug update-manager' in a terminal."
++msgstr ""
++"如全都不對,請在終端機內輸入指令「ubuntu-bug update-manager」回報錯誤。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:711
++#: ../UpdateManager/UpdateManager.py:1031
++msgid "Could not calculate the upgrade"
++msgstr "無法計算升級"
++
++#: ../DistUpgrade/DistUpgradeCache.py:762
++msgid "Error authenticating some packages"
++msgstr "認證一些套件時發生錯誤"
++
++#: ../DistUpgrade/DistUpgradeCache.py:763
++msgid ""
++"It was not possible to authenticate some packages. This may be a transient "
++"network problem. You may want to try again later. See below for a list of "
++"unauthenticated packages."
++msgstr ""
++"無法驗證部份套件。可能是因為短時間的網路問題。您可以稍候再試一次。下面是未被"
++"驗證的套件清單。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:783
++#, python-format
++msgid ""
++"The package '%s' is marked for removal but it is in the removal blacklist."
++msgstr "套件「%s」標記作移除,但它在移除黑名單中。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:787
++#, python-format
++msgid "The essential package '%s' is marked for removal."
++msgstr "必要套件「%s」被標記作移除。"
++
++#: ../DistUpgrade/DistUpgradeCache.py:796
++#, python-format
++msgid "Trying to install blacklisted version '%s'"
++msgstr "正在嘗試安裝黑名單版本「%s」"
++
++#: ../DistUpgrade/DistUpgradeCache.py:914
++#, python-format
++msgid "Can't install '%s'"
++msgstr "無法安裝「%s」"
++
++#: ../DistUpgrade/DistUpgradeCache.py:915
++msgid ""
++"It was impossible to install a required package. Please report this as a bug "
++"using 'ubuntu-bug update-manager' in a terminal."
++msgstr ""
++"無法安裝必要的套件。請在終端機內輸入「ubuntu-bug update-manager」回報錯誤。"
++
++#. FIXME: provide a list
++#: ../DistUpgrade/DistUpgradeCache.py:926
++msgid "Can't guess meta-package"
++msgstr "無法估計元套件 (meta-package)"
++
++#: ../DistUpgrade/DistUpgradeCache.py:927
++msgid ""
++"Your system does not contain a ubuntu-desktop, kubuntu-desktop, xubuntu-"
++"desktop or edubuntu-desktop package and it was not possible to detect which "
++"version of Ubuntu you are running.\n"
++" Please install one of the packages above first using synaptic or apt-get "
++"before proceeding."
++msgstr ""
++"您的系統沒有安裝 ubuntu-desktop,kubuntu-desktop 或 edubuntu-desktop 套件,因"
++"此無法偵測正在使用那個版本的 Ubuntu。\n"
++" 請先使用 synaptic 或 apt-get 安裝上述其中一個套件再繼續作業"
++
++#: ../DistUpgrade/DistUpgradeController.py:114
++msgid "Reading cache"
++msgstr "正在讀取快取"
++
++#: ../DistUpgrade/DistUpgradeController.py:223
++msgid "Unable to get exclusive lock"
++msgstr "無法取得(使用)排他鎖定"
++
++#: ../DistUpgrade/DistUpgradeController.py:224
++msgid ""
++"This usually means that another package management application (like apt-get "
++"or aptitude) already running. Please close that application first."
++msgstr ""
++"這通常表示有其他的套件管理員程式(如 apt-get 或 aptitude)正在執行。請先關閉"
++"這些應用程式。"
++
++#: ../DistUpgrade/DistUpgradeController.py:257
++msgid "Upgrading over remote connection not supported"
++msgstr "不支援透過遠端連線升級"
++
++#: ../DistUpgrade/DistUpgradeController.py:258
++msgid ""
++"You are running the upgrade over a remote ssh connection with a frontend "
++"that does not support this. Please try a text mode upgrade with 'do-release-"
++"upgrade'.\n"
++"\n"
++"The upgrade will abort now. Please try without ssh."
++msgstr ""
++"您正在透過遠端 ssh 連線的前端介面執行更新,而此介面不支援。請試試純文字模式下"
++"以 'do-release-upgrade' 進行更新。\n"
++"\n"
++"目前更新將會中止。請透過非 ssh 連線重試。"
++
++#: ../DistUpgrade/DistUpgradeController.py:272
++msgid "Continue running under SSH?"
++msgstr "繼續執行於 SSH 中?"
++
++#: ../DistUpgrade/DistUpgradeController.py:273
++#, python-format
++msgid ""
++"This session appears to be running under ssh. It is not recommended to "
++"perform a upgrade over ssh currently because in case of failure it is harder "
++"to recover.\n"
++"\n"
++"If you continue, an additional ssh daemon will be started at port '%s'.\n"
++"Do you want to continue?"
++msgstr ""
++"此連線階段似乎是在 ssh 下執行。目前不建議在 ssh 連線下進行升級,因為若發生失"
++"敗將會較難以修復。\n"
++"\n"
++"若您繼續,一個額外的 ssh 背景程序將會啟動在 '%s' 連接埠。\n"
++"您想要繼續嗎?"
++
++#: ../DistUpgrade/DistUpgradeController.py:287
++msgid "Starting additional sshd"
++msgstr "啟動後備 sshd 中"
++
++#: ../DistUpgrade/DistUpgradeController.py:288
++#, python-format
++msgid ""
++"To make recovery in case of failure easier, an additional sshd will be "
++"started on port '%s'. If anything goes wrong with the running ssh you can "
++"still connect to the additional one.\n"
++msgstr ""
++"為在失敗時更易進行修復,一個後備 sshd 將在‘%s’埠被啟動。如果使用中的 ssh 有任"
++"何問題,您仍可以連接後備的 sshd 。\n"
++
++#: ../DistUpgrade/DistUpgradeController.py:296
++#, python-format
++msgid ""
++"If you run a firewall, you may need to temporarily open this port. As this "
++"is potentially dangerous it's not done automatically. You can open the port "
++"with e.g.:\n"
++"'%s'"
++msgstr ""
++"若您有執行防火牆,您可能需要暫時開啟此連接埠。由於此動作存在潛在危險,系統不"
++"會自動執行。您可以這樣開啟連接埠:\n"
++"「%s」"
++
++#: ../DistUpgrade/DistUpgradeController.py:368
++#: ../DistUpgrade/DistUpgradeController.py:413
++msgid "Can not upgrade"
++msgstr "無法升級"
++
++#: ../DistUpgrade/DistUpgradeController.py:369
++#, python-format
++msgid "An upgrade from '%s' to '%s' is not supported with this tool."
++msgstr "這個工具不支援從‘%s’到‘%s’的升級"
++
++#: ../DistUpgrade/DistUpgradeController.py:378
++msgid "Sandbox setup failed"
++msgstr "沙堆(Sandbox)架設失敗"
++
++#: ../DistUpgrade/DistUpgradeController.py:379
++msgid "It was not possible to create the sandbox environment."
++msgstr "不可能建立沙堆(sandbox)環境。"
++
++#: ../DistUpgrade/DistUpgradeController.py:385
++msgid "Sandbox mode"
++msgstr "沙堆(Sandbox)模式"
++
++#: ../DistUpgrade/DistUpgradeController.py:386
++#, python-format
++msgid ""
++"This upgrade is running in sandbox (test) mode. All changes are written to "
++"'%s' and will be lost on the next reboot.\n"
++"\n"
++"*No* changes written to a system directory from now until the next reboot "
++"are permanent."
++msgstr ""
++"此升級程序正以沙箱 (測試) 模式執行。所有的變更會寫入「%s」,下次重新開機後會"
++"消失。\n"
++"\n"
++"從現在起直到下次重新開機前,任何寫入系統目錄的變更都「不會」被留存。"
++
++#: ../DistUpgrade/DistUpgradeController.py:414
++msgid ""
++"Your python install is corrupted. Please fix the '/usr/bin/python' symlink."
++msgstr "您的 python 安裝已毀損。請修正 ‘/usr/bin/python’ 的符號連結。"
++
++#: ../DistUpgrade/DistUpgradeController.py:440
++msgid "Package 'debsig-verify' is installed"
++msgstr "套件 'debsig-verify' 安裝完成。"
++
++#: ../DistUpgrade/DistUpgradeController.py:441
++msgid ""
++"The upgrade can not continue with that package installed.\n"
++"Please remove it with synaptic or 'apt-get remove debsig-verify' first and "
++"run the upgrade again."
++msgstr ""
++"此已安裝的套件令升級無法繼續,請使用 synaptic 或命令 'apt-get remove debsig-"
++"verify' 移除它後再次進行升級。"
++
++#: ../DistUpgrade/DistUpgradeController.py:453
++#, python-format
++msgid "Can not write to '%s'"
++msgstr "無法寫入「%s」"
++
++#: ../DistUpgrade/DistUpgradeController.py:454
++#, python-format
++msgid ""
++"Its not possible to write to the system directory '%s' on your system. The "
++"upgrade can not continue.\n"
++"Please make sure that the system directory is writable."
++msgstr ""
++"無法寫入您的系統目錄「%s」。升級程序無法繼續。\n"
++"請確認該系統目錄可以寫入。"
++
++#: ../DistUpgrade/DistUpgradeController.py:465
++msgid "Include latest updates from the Internet?"
++msgstr "要否包括來自網際網路的最新更新?"
++
++#: ../DistUpgrade/DistUpgradeController.py:466
++msgid ""
++"The upgrade system can use the internet to automatically download the latest "
++"updates and install them during the upgrade.  If you have a network "
++"connection this is highly recommended.\n"
++"\n"
++"The upgrade will take longer, but when it is complete, your system will be "
++"fully up to date.  You can choose not to do this, but you should install the "
++"latest updates soon after upgrading.\n"
++"If you answer 'no' here, the network is not used at all."
++msgstr ""
++"升級系統可自動由網際網路下載最新更新並於升級時安裝。如您有網路連線,建議使用"
++"這方法。\n"
++"\n"
++"升級時間會較長,但完成後,您的系統就會完全在最新狀態。您可以選擇現在不進行這"
++"工作,但是在升級後,您應該要盡快安裝最新的更新。\n"
++"如果您在此回答「否」,將完全不會使用網路。"
++
++#: ../DistUpgrade/DistUpgradeController.py:686
++#, python-format
++msgid "disabled on upgrade to %s"
++msgstr "因升級至 %s 停用"
++
++#: ../DistUpgrade/DistUpgradeController.py:713
++msgid "No valid mirror found"
++msgstr "找不到有效的鏡像站"
++
++#: ../DistUpgrade/DistUpgradeController.py:714
++#, python-format
++msgid ""
++"While scanning your repository information no mirror entry for the upgrade "
++"was found. This can happen if you run a internal mirror or if the mirror "
++"information is out of date.\n"
++"\n"
++"Do you want to rewrite your 'sources.list' file anyway? If you choose 'Yes' "
++"here it will update all '%s' to '%s' entries.\n"
++"If you select 'No' the upgrade will cancel."
++msgstr ""
++"掃描閣下套件庫時沒有發現升級映射項目資訊。如果您運行內部映射或者映射資訊已經"
++"過期,就會發生這種情況。\n"
++"\n"
++"是否無論如何都希望覆寫您的「sources.list」檔案?如選「是」則將會將所有「%s」"
++"更新成「%s」項目。\n"
++"如選「否」則會取消更新。"
++
++#. hm, still nothing useful ...
++#: ../DistUpgrade/DistUpgradeController.py:734
++msgid "Generate default sources?"
++msgstr "產生預設的來源?"
++
++#: ../DistUpgrade/DistUpgradeController.py:735
++#, python-format
++msgid ""
++"After scanning your 'sources.list' no valid entry for '%s' was found.\n"
++"\n"
++"Should default entries for '%s' be added? If you select 'No', the upgrade "
++"will cancel."
++msgstr ""
++"在掃描您的「sources.list」後,沒找到與「%s」有效的項目。\n"
++"\n"
++"要新增「%s」的預設項目嗎?如果您選擇「否」則會取消升級。"
++
++#: ../DistUpgrade/DistUpgradeController.py:770
++msgid "Repository information invalid"
++msgstr "套件庫資料無效"
++
++#: ../DistUpgrade/DistUpgradeController.py:771
++msgid ""
++"Upgrading the repository information resulted in a invalid file so a bug "
++"reporting process is being started."
++msgstr "升級套件庫資訊導致檔案無效,因此正在啟動臭蟲回報程序"
++
++#: ../DistUpgrade/DistUpgradeController.py:778
++msgid "Third party sources disabled"
++msgstr "已停用第三方來源"
++
++#: ../DistUpgrade/DistUpgradeController.py:779
++msgid ""
++"Some third party entries in your sources.list were disabled. You can re-"
++"enable them after the upgrade with the 'software-properties' tool or your "
++"package manager."
++msgstr ""
++"sources.list 中的某些第三方項目已停用。以「軟體來源」工具或套件管理員升級後可"
++"將之重新啟用。"
++
++#: ../DistUpgrade/DistUpgradeController.py:819
++msgid "Package in inconsistent state"
++msgid_plural "Packages in inconsistent state"
++msgstr[0] "套件在不一致狀態"
++
++#: ../DistUpgrade/DistUpgradeController.py:822
++#, python-format
++msgid ""
++"The package '%s' is in an inconsistent state and needs to be reinstalled, "
++"but no archive can be found for it. Please reinstall the package manually or "
++"remove it from the system."
++msgid_plural ""
++"The packages '%s' are in an inconsistent state and need to be reinstalled, "
++"but no archive can be found for them. Please reinstall the packages manually "
++"or remove them from the system."
++msgstr[0] ""
++"這個套件 '%s' 狀態不一致而需要重新安裝,但找不到它的套件。請手動地重新安裝套"
++"件或將它由系統中移除。"
++
++#: ../DistUpgrade/DistUpgradeController.py:870
++msgid "Error during update"
++msgstr "更新時發生錯誤"
++
++#: ../DistUpgrade/DistUpgradeController.py:871
++msgid ""
++"A problem occurred during the update. This is usually some sort of network "
++"problem, please check your network connection and retry."
++msgstr "更新時發生錯誤。這可能是某些網路問題,試檢查網路連線後再試。"
++
++#. print("on_button_install_clicked")
++#: ../DistUpgrade/DistUpgradeController.py:880
++#: ../UpdateManager/UpdateManager.py:757
++msgid "Not enough free disk space"
++msgstr "磁碟空間不足"
++
++#: ../DistUpgrade/DistUpgradeController.py:881
++#, python-format
++msgid ""
++"The upgrade has aborted. The upgrade needs a total of %s free space on disk "
++"'%s'. Please free at least an additional %s of disk space on '%s'. Empty "
++"your trash and remove temporary packages of former installations using 'sudo "
++"apt-get clean'."
++msgstr ""
++"已放棄升級。升級程序總共需要  %s 可用空間於磁碟「%s」。請釋放至少額外 %s 的磁"
++"碟空間於磁碟「%s」。清理您的回收筒,並使用 'sudo apt-get clean' 來移除之前安"
++"裝時的暫時性套件。"
++
++#. calc the dist-upgrade and see if the removals are ok/expected
++#. do the dist-upgrade
++#: ../DistUpgrade/DistUpgradeController.py:910
++#: ../DistUpgrade/DistUpgradeController.py:1692
++msgid "Calculating the changes"
++msgstr "正在計算所有的更動"
++
++#. ask the user
++#: ../DistUpgrade/DistUpgradeController.py:942
++msgid "Do you want to start the upgrade?"
++msgstr "要開始升級嗎?"
++
++#: ../DistUpgrade/DistUpgradeController.py:1008
++msgid "Upgrade canceled"
++msgstr "升級取消了"
++
++#: ../DistUpgrade/DistUpgradeController.py:1009
++msgid ""
++"The upgrade will cancel now and the original system state will be restored. "
++"You can resume the upgrade at a later time."
++msgstr "現在將取消升級,並且還原至原始系統。您可以在之後繼續升級。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1015
++#: ../DistUpgrade/DistUpgradeController.py:1149
++msgid "Could not download the upgrades"
++msgstr "無法下載升級套件"
++
++#: ../DistUpgrade/DistUpgradeController.py:1016
++msgid ""
++"The upgrade has aborted. Please check your Internet connection or "
++"installation media and try again. All files downloaded so far have been kept."
++msgstr ""
++"升級已中止。請檢查您的網際網路連線,或安裝媒體並重試。所有目前已下載的檔案都"
++"會被保留。"
++
++#. FIXME: strings are not good, but we are in string freeze
++#. currently
++#: ../DistUpgrade/DistUpgradeController.py:1100
++#: ../DistUpgrade/DistUpgradeController.py:1137
++#: ../DistUpgrade/DistUpgradeController.py:1242
++msgid "Error during commit"
++msgstr "提交時發生錯誤"
++
++#. generate a new cache
++#: ../DistUpgrade/DistUpgradeController.py:1102
++#: ../DistUpgrade/DistUpgradeController.py:1139
++#: ../DistUpgrade/DistUpgradeController.py:1281
++msgid "Restoring original system state"
++msgstr "回復原有系統狀態"
++
++#: ../DistUpgrade/DistUpgradeController.py:1103
++#: ../DistUpgrade/DistUpgradeController.py:1118
++#: ../DistUpgrade/DistUpgradeController.py:1140
++msgid "Could not install the upgrades"
++msgstr "無法安裝升級"
++
++#. invoke the frontend now and show a error message
++#: ../DistUpgrade/DistUpgradeController.py:1108
++msgid ""
++"The upgrade has aborted. Your system could be in an unusable state. A "
++"recovery will run now (dpkg --configure -a)."
++msgstr ""
++"已放棄升級。您的系統可能處於不穩定狀態。現在將執行復原程序 (dpkg --configure "
++"-a)。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1113
++#, python-format
++msgid ""
++"\n"
++"\n"
++"Please report this bug in a browser at http://bugs.launchpad.net/ubuntu/"
++"+source/update-manager/+filebug and attach the files in /var/log/dist-"
++"upgrade/ to the bug report.\n"
++"%s"
++msgstr ""
++"\n"
++"\n"
++"請透過瀏覽器回報此臭蟲於 http://bugs.launchpad.net/ubuntu/+source/update-"
++"manager/+filebug ,並請附加 /var/log/dist-upgrade/ 內的檔案至臭蟲回報中。\n"
++"%s"
++
++#: ../DistUpgrade/DistUpgradeController.py:1150
++msgid ""
++"The upgrade has aborted. Please check your Internet connection or "
++"installation media and try again. "
++msgstr "已放棄升級。請檢查您的網際網路連線或安裝媒體,接著再試一次。 "
++
++#: ../DistUpgrade/DistUpgradeController.py:1230
++msgid "Remove obsolete packages?"
++msgstr "移除廢棄的套件?"
++
++#: ../DistUpgrade/DistUpgradeController.py:1231
++#: ../DistUpgrade/DistUpgrade.ui.h:8
++msgid "_Keep"
++msgstr "保留(_K)"
++
++#: ../DistUpgrade/DistUpgradeController.py:1231
++msgid "_Remove"
++msgstr "移除(_R)"
++
++#: ../DistUpgrade/DistUpgradeController.py:1243
++msgid ""
++"A problem occurred during the clean-up. Please see the below message for "
++"more information. "
++msgstr "在清理時發生一些問題。詳情請參閱以下訊息。 "
++
++#. FIXME: instead of error out, fetch and install it
++#. here
++#: ../DistUpgrade/DistUpgradeController.py:1319
++msgid "Required depends is not installed"
++msgstr "必需的相依套件未被安裝"
++
++#: ../DistUpgrade/DistUpgradeController.py:1320
++#, python-format
++msgid "The required dependency '%s' is not installed. "
++msgstr "必需的相依套件‘%s’未被安裝。 "
++
++#. sanity check (check for ubuntu-desktop, brokenCache etc)
++#. then open the cache (again)
++#: ../DistUpgrade/DistUpgradeController.py:1588
++#: ../DistUpgrade/DistUpgradeController.py:1653
++msgid "Checking package manager"
++msgstr "正在檢查套件管理員"
++
++#: ../DistUpgrade/DistUpgradeController.py:1593
++msgid "Preparing the upgrade failed"
++msgstr "準備升級失敗"
++
++#: ../DistUpgrade/DistUpgradeController.py:1594
++msgid ""
++"Preparing the system for the upgrade failed so a bug reporting process is "
++"being started."
++msgstr "準備系統以供升級的動作失敗,所以正在啟動臭蟲回報程序。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1608
++msgid "Getting upgrade prerequisites failed"
++msgstr "取得升級先決元件失敗"
++
++#: ../DistUpgrade/DistUpgradeController.py:1609
++msgid ""
++"The system was unable to get the prerequisites for the upgrade. The upgrade "
++"will abort now and restore the original system state.\n"
++"\n"
++"Additionally, a bug reporting process is being started."
++msgstr ""
++"本系統無法達到升級的先決條件。升級將立刻中止並且還原至原始系統狀態。\n"
++"\n"
++"此外,臭蟲回報程序正在啟動中。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1637
++msgid "Updating repository information"
++msgstr "正在更新套件庫資訊"
++
++#: ../DistUpgrade/DistUpgradeController.py:1644
++msgid "Failed to add the cdrom"
++msgstr "無法加入光碟"
++
++#: ../DistUpgrade/DistUpgradeController.py:1645
++msgid "Sorry, adding the cdrom was not successful."
++msgstr "很抱歉,沒有成功加入光碟。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1673
++msgid "Invalid package information"
++msgstr "無效的套件資訊"
++
++#: ../DistUpgrade/DistUpgradeController.py:1674
++msgid "After updating your package "
++msgstr ""
++
++#: ../DistUpgrade/DistUpgradeController.py:1698
++#: ../DistUpgrade/DistUpgradeController.py:1750
++msgid "Fetching"
++msgstr "接收中"
++
++#: ../DistUpgrade/DistUpgradeController.py:1704
++#: ../DistUpgrade/DistUpgradeController.py:1754
++msgid "Upgrading"
++msgstr "升級中"
++
++#. don't abort here, because it would restore the sources.list
++#: ../DistUpgrade/DistUpgradeController.py:1709
++#: ../DistUpgrade/DistUpgradeController.py:1756
++#: ../DistUpgrade/DistUpgradeController.py:1763
++#: ../DistUpgrade/DistUpgradeController.py:1774
++msgid "Upgrade complete"
++msgstr "升級完成"
++
++#: ../DistUpgrade/DistUpgradeController.py:1710
++#: ../DistUpgrade/DistUpgradeController.py:1757
++#: ../DistUpgrade/DistUpgradeController.py:1764
++msgid ""
++"The upgrade has completed but there were errors during the upgrade process."
++msgstr "升級已經完成,但在升級過程中有發生錯誤。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1717
++msgid "Searching for obsolete software"
++msgstr "搜尋廢棄的軟體中"
++
++#: ../DistUpgrade/DistUpgradeController.py:1726
++msgid "System upgrade is complete."
++msgstr "系統升級完成。"
++
++#: ../DistUpgrade/DistUpgradeController.py:1775
++msgid "The partial upgrade was completed."
++msgstr "部份升級完成。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:204
++msgid "evms in use"
++msgstr "有軟體正使用 evms"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:205
++msgid ""
++"Your system uses the 'evms' volume manager in /proc/mounts. The 'evms' "
++"software is no longer supported, please switch it off and run the upgrade "
++"again when this is done."
++msgstr ""
++"您的系統於 /proc/mounts 使用 'evms' volume 管理程式。'evms' 軟體已不受支援,"
++"請將其關閉再執行升級工作。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:502
++msgid "Your graphics hardware may not be fully supported in Ubuntu 12.04 LTS."
++msgstr "您的繪圖硬體可能無法被 Ubuntu 12.04 LTS 完整支援。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:504
++msgid ""
++"The support in Ubuntu 12.04 LTS for your Intel graphics hardware is limited "
++"and you may encounter problems after the upgrade. For more information see "
++"https://wiki.ubuntu.com/X/Bugs/UpdateManagerWarningForI8xx Do you want to "
++"continue with the upgrade?"
++msgstr ""
++"Ubuntu 12.04 LTS 對您的 Intel 繪圖硬體的支援有限,升級之後您可能會碰到一些問"
++"題。更多資訊可以查看 \"https://wiki.ubuntu.com/X/Bugs/"
++"UpdateManagerWarningForI8xx\"。您是否要繼續升級?"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:526
++#: ../DistUpgrade/DistUpgradeQuirks.py:554
++#: ../DistUpgrade/DistUpgradeQuirks.py:581
++msgid ""
++"Upgrading may reduce desktop effects, and performance in games and other "
++"graphically intensive programs."
++msgstr "升級可能減低桌面特效和遊戲及其他著重圖形程式的表現。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:530
++#: ../DistUpgrade/DistUpgradeQuirks.py:558
++msgid ""
++"This computer is currently using the NVIDIA 'nvidia' graphics driver. No "
++"version of this driver is available that works with your video card in "
++"Ubuntu 10.04 LTS.\n"
++"\n"
++"Do you want to continue?"
++msgstr ""
++"這個電腦目前正使用 NVIDIA 的「nvidia」圖形驅動程式。這個驅動程式沒有任何版本"
++"可在 Ubuntu 10.04 LTS 中正常驅動您的硬體。\n"
++"\n"
++"是否要繼續?"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:585
++msgid ""
++"This computer is currently using the AMD 'fglrx' graphics driver. No version "
++"of this driver is available that works with your hardware in Ubuntu 10.04 "
++"LTS.\n"
++"\n"
++"Do you want to continue?"
++msgstr ""
++"這個電腦目前正使用 AMD 的「fglrx」圖形驅動程式。這個驅動程式沒有任何版本可在 "
++"Ubuntu 10.04 LTS 中正常驅動您的硬體。\n"
++"\n"
++"是否要繼續?"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:615
++msgid "No i686 CPU"
++msgstr "無 i686 CPU"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:616
++msgid ""
++"Your system uses an i586 CPU or a CPU that does not have the 'cmov' "
++"extension. All packages were built with optimizations requiring i686 as the "
++"minimal architecture. It is not possible to upgrade your system to a new "
++"Ubuntu release with this hardware."
++msgstr ""
++"您的系統使用 i586 CPU,或是不支援 'cmov' 擴充功能的 CPU。所有套件都以 i686 架"
++"構為最佳化目標來建置,所以 CPU 至少需要有 i686 等級。對於您目前的硬體來說,您"
++"無法將系統升級到最新的 Ubuntu 發行。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:652
++msgid "No ARMv6 CPU"
++msgstr "無 ARMv6 處理器"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:653
++msgid ""
++"Your system uses an ARM CPU that is older than the ARMv6 architecture. All "
++"packages in karmic were built with optimizations requiring ARMv6 as the "
++"minimal architecture. It is not possible to upgrade your system to a new "
++"Ubuntu release with this hardware."
++msgstr ""
++"您系統使用的 ARM 處理器舊於 ARMv6 架構。所有 karmic 套件都是以 ARMv6 為最低架"
++"構優化建造的。所以伴隨此硬體無法升級您的系統到新的 Ubuntu 版本。"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:673
++msgid "No init available"
++msgstr "無法初始化"
++
++#: ../DistUpgrade/DistUpgradeQuirks.py:674
++msgid ""
++"Your system appears to be a virtualised environment without an init daemon, "
++"e.g. Linux-VServer. Ubuntu 10.04 LTS cannot function within this type of "
++"environment, requiring an update to your virtual machine configuration "
++"first.\n"
++"\n"
++"Are you sure you want to continue?"
++msgstr ""
++"您的系統似乎處於虛擬化環境且無初始化程序,例如 Linux-VServer。Ubuntu 10.04 "
++"LTS 無法於此環境執行,需要先更新您的虛擬機器設定。\n"
++"\n"
++"您確定想要繼續?"
++
++#: ../DistUpgrade/DistUpgradeMain.py:65
++msgid "Sandbox upgrade using aufs"
++msgstr "使用 aufs 作為沙堆升級"
++
++#: ../DistUpgrade/DistUpgradeMain.py:67
++msgid "Use the given path to search for a cdrom with upgradable packages"
++msgstr "使用指定路徑搜尋附有升級套件的光碟"
++
++#: ../DistUpgrade/DistUpgradeMain.py:73
++msgid ""
++"Use frontend. Currently available: \n"
++"DistUpgradeViewText, DistUpgradeViewGtk, DistUpgradeViewKDE"
++msgstr ""
++"使用前端介面。可供選擇的有: \n"
++"DistUpgradeViewText (純文字), DistUpgradeViewGtk (GTK+), DistUpgradeViewKDE "
++"(KDE)"
++
++#: ../DistUpgrade/DistUpgradeMain.py:76
++msgid "*DEPRECATED* this option will be ignored"
++msgstr "*已棄用* 這個選項會被忽略"
++
++#: ../DistUpgrade/DistUpgradeMain.py:79
++msgid "Perform a partial upgrade only (no sources.list rewriting)"
++msgstr "只進行部份升級 (無須修改 sources.list)"
++
++#: ../DistUpgrade/DistUpgradeMain.py:82
++msgid "Disable GNU screen support"
++msgstr "停用 GNU 螢幕支援"
++
++#: ../DistUpgrade/DistUpgradeMain.py:84
++msgid "Set datadir"
++msgstr "設定資料目錄"
++
++#. print("mediaChange %s %s" % (medium, drive))
++#: ../DistUpgrade/DistUpgradeViewGtk.py:114
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:117
++#: ../DistUpgrade/DistUpgradeViewKDE.py:195
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:155
++#, python-format
++msgid "Please insert '%s' into the drive '%s'"
++msgstr "請將‘%s’放入光碟機‘%s’"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:135
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:138
++#: ../DistUpgrade/DistUpgradeViewKDE.py:209
++msgid "Fetching is complete"
++msgstr "接收完成"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:146
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:149
++#: ../DistUpgrade/DistUpgradeViewKDE.py:222
++#, python-format
++msgid "Fetching file %li of %li at %sB/s"
++msgstr "接收第 %li 個檔案 (共 %li 個檔案,速度為 %sB/s)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:149
++#: ../DistUpgrade/DistUpgradeViewGtk.py:296
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:152
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:309
++#: ../DistUpgrade/DistUpgradeViewKDE.py:223
++#: ../DistUpgrade/DistUpgradeViewKDE.py:371
++#, python-format
++msgid "About %s remaining"
++msgstr "大約剩下 %s"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:152
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:155
++#: ../DistUpgrade/DistUpgradeViewKDE.py:225
++#, python-format
++msgid "Fetching file %li of %li"
++msgstr "接收第 %li 個檔案 (共 %li 個)"
++
++#. FIXME: add support for the timeout
++#. of the terminal (to display something useful then)
++#. -> longer term, move this code into python-apt
++#: ../DistUpgrade/DistUpgradeViewGtk.py:183
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:186
++#: ../DistUpgrade/DistUpgradeViewKDE.py:262
++msgid "Applying changes"
++msgstr "正在套用變更"
++
++#. we do not report followup errors from earlier failures
++#: ../DistUpgrade/DistUpgradeViewGtk.py:208
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:212
++#: ../DistUpgrade/DistUpgradeViewKDE.py:275
++msgid "dependency problems - leaving unconfigured"
++msgstr "相依問題 - 保留為未設定"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:213
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:217
++#: ../DistUpgrade/DistUpgradeViewKDE.py:277
++#, python-format
++msgid "Could not install '%s'"
++msgstr "無法安裝‘%s’"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:214
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:218
++#: ../DistUpgrade/DistUpgradeViewKDE.py:278
++#, python-format
++msgid ""
++"The upgrade will continue but the '%s' package may not be in a working "
++"state. Please consider submitting a bug report about it."
++msgstr ""
++"此次更新將繼續但是 '%s' 套件可能無法運作。請考慮提交關於該套件的臭蟲報告。"
++
++#. self.expander.set_expanded(True)
++#: ../DistUpgrade/DistUpgradeViewGtk.py:231
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:235
++#: ../DistUpgrade/DistUpgradeViewKDE.py:299
++#, python-format
++msgid ""
++"Replace the customized configuration file\n"
++"'%s'?"
++msgstr ""
++"是否要覆蓋自訂的設定檔案\n"
++"‘%s’?"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:232
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:236
++#: ../DistUpgrade/DistUpgradeViewKDE.py:300
++msgid ""
++"You will lose any changes you have made to this configuration file if you "
++"choose to replace it with a newer version."
++msgstr "如果選擇以新版覆蓋,那麼將會失去您改變過的設定。"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:251
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:256
++#: ../DistUpgrade/DistUpgradeViewKDE.py:323
++msgid "The 'diff' command was not found"
++msgstr "找不到‘diff’指令"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:464
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:477
++#: ../DistUpgrade/DistUpgradeViewText.py:92
++msgid "A fatal error occurred"
++msgstr "發生嚴重錯誤"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:465
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:478
++msgid ""
++"Please report this as a bug (if you haven't already) and include the files /"
++"var/log/dist-upgrade/main.log and /var/log/dist-upgrade/apt.log in your "
++"report. The upgrade has aborted.\n"
++"Your original sources.list was saved in /etc/apt/sources.list.distUpgrade."
++msgstr ""
++"請回報此錯誤 (若您尚未回報) 並將檔案 /var/log/dist-upgrade/main.log 與 /var/"
++"log/dist-upgrade/apt.log 附在您的報告中。升級程序已取消。\n"
++"您原先的 sources.list 儲存於 /etc/apt/sources.list.distUpgrade。"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:482
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:495
++msgid "Ctrl-c pressed"
++msgstr "按下 Ctrl+c"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:483
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:496
++msgid ""
++"This will abort the operation and may leave the system in a broken state. "
++"Are you sure you want to do that?"
++msgstr "操作將被中止。這可能會造成系統的不完整。你確定要進行嗎?"
++
++#. append warning
++#: ../DistUpgrade/DistUpgradeViewGtk.py:631
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:629
++msgid "To prevent data loss close all open applications and documents."
++msgstr "為避免遺失資料,請關閉所有開啟的程式及文件。"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:645
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:643
++#, python-format
++msgid "No longer supported by Canonical (%s)"
++msgstr "不再受 Canonical 支援 (%s)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:646
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:644
++#, python-format
++msgid "<b>Downgrade (%s)</b>"
++msgstr "<b>降級 (%s)</b>"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:647
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:645
++#, python-format
++msgid "Remove (%s)"
++msgstr "移除 (%s)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:648
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:646
++#, python-format
++msgid "No longer needed (%s)"
++msgstr "不再需要 (%s)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:649
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:647
++#, python-format
++msgid "Install (%s)"
++msgstr "安裝 (%s)"
++
++#: ../DistUpgrade/DistUpgradeViewGtk.py:650
++#: ../DistUpgrade/DistUpgradeViewGtk3.py:648
++#, python-format
++msgid "Upgrade (%s)"
++msgstr "升級 (%s)"
++
++#. change = QMessageBox.question(None, _("Media Change"), msg, QMessageBox.Ok, QMessageBox.Cancel)
++#: ../DistUpgrade/DistUpgradeViewKDE.py:196
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:157
++msgid "Media Change"
++msgstr "媒體變更"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:335
++msgid "Show Difference >>>"
++msgstr "顯示差異 >>>"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:338
++msgid "<<< Hide Difference"
++msgstr "<<< 隱藏差異"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:554
++msgid "Error"
++msgstr "錯誤"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:568
++msgid "&Cancel"
++msgstr "取消(&C)"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:572
++#: ../DistUpgrade/DistUpgradeViewKDE.py:813
++msgid "&Close"
++msgstr "關閉(&C)"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:618
++msgid "Show Terminal >>>"
++msgstr "顯示終端畫面 >>>"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:621
++msgid "<<< Hide Terminal"
++msgstr "<<< 隱藏終端畫面"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:701
++msgid "Information"
++msgstr "資訊"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:751
++#: ../DistUpgrade/DistUpgradeViewKDE.py:796
++#: ../DistUpgrade/DistUpgradeViewKDE.py:799 ../DistUpgrade/DistUpgrade.ui.h:7
++msgid "Details"
++msgstr "詳情"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:777
++#, python-format
++msgid "No longer supported %s"
++msgstr "不再支援 %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:779
++#, python-format
++msgid "Remove %s"
++msgstr "移除 %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:781
++#: ../DistUpgrade/DistUpgradeViewText.py:182
++#, python-format
++msgid "Remove (was auto installed) %s"
++msgstr "移除 (曾是自動安裝的) %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:783
++#, python-format
++msgid "Install %s"
++msgstr "安裝 %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:785
++#, python-format
++msgid "Upgrade %s"
++msgstr "升級 %s"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:809
++#: ../DistUpgrade/DistUpgradeViewText.py:230
++msgid "Restart required"
++msgstr "需要重新開機"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:809
++msgid "<b><big>Restart the system to complete the upgrade</big></b>"
++msgstr "<b><big>重新啟動系統以完成更新</big></b>"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:812 ../DistUpgrade/DistUpgrade.ui.h:14
++#: ../data/gtkbuilder/UpdateManager.ui.h:26
++msgid "_Restart Now"
++msgstr "現在重新啟動(_R)"
++
++#. FIXME make this user friendly
++#: ../DistUpgrade/DistUpgradeViewKDE.py:830
++msgid ""
++"<b><big>Cancel the running upgrade?</big></b>\n"
++"\n"
++"The system could be in an unusable state if you cancel the upgrade. You are "
++"strongly advised to resume the upgrade."
++msgstr ""
++"<b><big>是否取消正進行的升級?</big></b>\n"
++"\n"
++"如果您取消升級,系統可能會在不穩定的狀態。強烈建議您繼續升級工作。"
++
++#: ../DistUpgrade/DistUpgradeViewKDE.py:834
++msgid "Cancel Upgrade?"
++msgstr "要取消升級嗎?"
++
++#: ../DistUpgrade/DistUpgradeView.py:61
++#, python-format
++msgid "%li day"
++msgid_plural "%li days"
++msgstr[0] "%li 日"
++
++#: ../DistUpgrade/DistUpgradeView.py:63
++#, python-format
++msgid "%li hour"
++msgid_plural "%li hours"
++msgstr[0] "%li 小時"
++
++#: ../DistUpgrade/DistUpgradeView.py:65
++#, python-format
++msgid "%li minute"
++msgid_plural "%li minutes"
++msgstr[0] "%li 分鐘"
++
++#: ../DistUpgrade/DistUpgradeView.py:66
++#, python-format
++msgid "%li second"
++msgid_plural "%li seconds"
++msgstr[0] "%li 秒"
++
++#. TRANSLATORS: you can alter the ordering of the remaining time
++#. information here if you shuffle %(str_days)s %(str_hours)s %(str_minutes)s
++#. around. Make sure to keep all '$(str_*)s' in the translated string
++#. and do NOT change anything appart from the ordering.
++#.
++#. %(str_hours)s will be either "1 hour" or "2 hours" depending on the
++#. plural form
++#.
++#. Note: most western languages will not need to change this
++#: ../DistUpgrade/DistUpgradeView.py:82
++#, python-format
++msgid "%(str_days)s %(str_hours)s"
++msgstr "%(str_days)s %(str_hours)s"
++
++#. TRANSLATORS: you can alter the ordering of the remaining time
++#. information here if you shuffle %(str_hours)s %(str_minutes)s
++#. around. Make sure to keep all '$(str_*)s' in the translated string
++#. and do NOT change anything appart from the ordering.
++#.
++#. %(str_hours)s will be either "1 hour" or "2 hours" depending on the
++#. plural form
++#.
++#. Note: most western languages will not need to change this
++#: ../DistUpgrade/DistUpgradeView.py:100
++#, python-format
++msgid "%(str_hours)s %(str_minutes)s"
++msgstr "%(str_hours)s又 %(str_minutes)s"
++
++#. 56 kbit
++#. 1Mbit = 1024 kbit
++#: ../DistUpgrade/DistUpgradeView.py:151
++#, python-format
++msgid ""
++"This download will take about %s with a 1Mbit DSL connection and about %s "
++"with a 56k modem."
++msgstr "這次下載所需時間在 1M DSL 連線大約要 %s,用 56k 數據機大約要 %s。"
++
++#. if we have a estimated speed, use it
++#: ../DistUpgrade/DistUpgradeView.py:155
++#, python-format
++msgid "This download will take about %s with your connection. "
++msgstr "依照您的連線速率,此下載將要約 %s 的時間。 "
++
++#. Declare these translatable strings from the .ui files here so that
++#. xgettext picks them up.
++#: ../DistUpgrade/DistUpgradeView.py:259 ../DistUpgrade/DistUpgrade.ui.h:21
++msgid "Preparing to upgrade"
++msgstr "準備升級中"
++
++#: ../DistUpgrade/DistUpgradeView.py:260
++msgid "Getting new software channels"
++msgstr "正取得新軟體頻道"
++
++#: ../DistUpgrade/DistUpgradeView.py:261 ../DistUpgrade/DistUpgrade.ui.h:23
++msgid "Getting new packages"
++msgstr "取得新套件"
++
++#: ../DistUpgrade/DistUpgradeView.py:262 ../DistUpgrade/DistUpgrade.ui.h:26
++msgid "Installing the upgrades"
++msgstr "安裝升級中"
++
++#: ../DistUpgrade/DistUpgradeView.py:263 ../DistUpgrade/DistUpgrade.ui.h:25
++msgid "Cleaning up"
++msgstr "清理中"
++
++#: ../DistUpgrade/DistUpgradeView.py:348
++#, python-format
++msgid ""
++"%(amount)d installed package is no longer supported by Canonical. You can "
++"still get support from the community."
++msgid_plural ""
++"%(amount)d installed packages are no longer supported by Canonical. You can "
++"still get support from the community."
++msgstr[0] ""
++"%(amount)d 個已安裝套件不再受 Canonical 支援。您仍可以取得來自社群的支援。"
++
++#. FIXME: make those two separate lines to make it clear
++#. that the "%" applies to the result of ngettext
++#: ../DistUpgrade/DistUpgradeView.py:357
++#, python-format
++msgid "%d package is going to be removed."
++msgid_plural "%d packages are going to be removed."
++msgstr[0] "即將移除 %d 個套件。"
++
++#: ../DistUpgrade/DistUpgradeView.py:362
++#, python-format
++msgid "%d new package is going to be installed."
++msgid_plural "%d new packages are going to be installed."
++msgstr[0] "即將安裝 %d 個新套件。"
++
++#: ../DistUpgrade/DistUpgradeView.py:368
++#, python-format
++msgid "%d package is going to be upgraded."
++msgid_plural "%d packages are going to be upgraded."
++msgstr[0] "即將升級 %d 個套件。"
++
++#: ../DistUpgrade/DistUpgradeView.py:373
++#, python-format
++msgid ""
++"\n"
++"\n"
++"You have to download a total of %s. "
++msgstr ""
++"\n"
++"\n"
++"要下載共%s。 "
++
++#: ../DistUpgrade/DistUpgradeView.py:378
++msgid ""
++"Installing the upgrade can take several hours. Once the download has "
++"finished, the process cannot be canceled."
++msgstr "安裝升級可能會花上幾個鐘頭。一旦下載完成,程序便無法取消。"
++
++#: ../DistUpgrade/DistUpgradeView.py:382
++msgid ""
++"Fetching and installing the upgrade can take several hours. Once the "
++"download has finished, the process cannot be canceled."
++msgstr "升級的擷取與安裝可能花上數個鐘頭。一旦下載完成,升級程序無法取消。"
++
++#: ../DistUpgrade/DistUpgradeView.py:387
++msgid "Removing the packages can take several hours. "
++msgstr "移除套件可能會花上幾個鐘頭。 "
++
++#. FIXME: this should go into DistUpgradeController
++#: ../DistUpgrade/DistUpgradeView.py:392 ../UpdateManager/UpdateManager.py:676
++msgid "The software on this computer is up to date."
++msgstr "這臺電腦上的軟體已處最新狀態。"
++
++#: ../DistUpgrade/DistUpgradeView.py:393
++msgid ""
++"There are no upgrades available for your system. The upgrade will now be "
++"canceled."
++msgstr "您的系統已在最新狀態。現在將取消升級動作。"
++
++#: ../DistUpgrade/DistUpgradeView.py:406
++msgid "Reboot required"
++msgstr "需要重新開機"
++
++#: ../DistUpgrade/DistUpgradeView.py:407
++msgid ""
++"The upgrade is finished and a reboot is required. Do you want to do this now?"
++msgstr "升級已經完成並需要重新開機。是否現在重新開機?"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:72
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:72
++#, python-format
++msgid "authenticate '%(file)s' against '%(signature)s' "
++msgstr "以「%(signature)s」驗證「%(file)s」 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:131
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:131
++#, python-format
++msgid "extracting '%s'"
++msgstr "正在抽出「%s」"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:151
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:152
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:151
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:152
++msgid "Could not run the upgrade tool"
++msgstr "無法執行升級工具"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:152
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:152
++msgid ""
++"This is most likely a bug in the upgrade tool. Please report it as a bug "
++"using the command 'ubuntu-bug update-manager'."
++msgstr ""
++"這可能是升級工具的錯誤,請使用指令「ubuntu-bug update-manager」回報錯誤。"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:227
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:227
++msgid "Upgrade tool signature"
++msgstr "升級工具簽署"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:234
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:234
++msgid "Upgrade tool"
++msgstr "升級工具"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:268
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:268
++msgid "Failed to fetch"
++msgstr "接收失敗"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:269
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:269
++msgid "Fetching the upgrade failed. There may be a network problem. "
++msgstr "接收升級套件失敗。可能是網路問題。 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:273
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:273
++msgid "Authentication failed"
++msgstr "認證失敗"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:274
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:274
++msgid ""
++"Authenticating the upgrade failed. There may be a problem with the network "
++"or with the server. "
++msgstr "認證升級套件失敗。可能是因為跟伺服器的網路連線出現問題。 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:279
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:279
++msgid "Failed to extract"
++msgstr "解壓失敗"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:280
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:280
++msgid ""
++"Extracting the upgrade failed. There may be a problem with the network or "
++"with the server. "
++msgstr "升級套件解壓失敗。可能是因為網路或伺服器出現問題。 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:285
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:285
++msgid "Verification failed"
++msgstr "檢驗失敗"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:286
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:286
++msgid ""
++"Verifying the upgrade failed.  There may be a problem with the network or "
++"with the server. "
++msgstr "檢驗升級套件失敗。可能是因為網路或伺服器出現問題。 "
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:300
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:306
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:300
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:306
++msgid "Can not run the upgrade"
++msgstr "不能進行升級"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:301
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:301
++msgid ""
++"This usually is caused by a system where /tmp is mounted noexec. Please "
++"remount without noexec and run the upgrade again."
++msgstr ""
++"這通常是由使用 noexec 掛載 /tmp 的系統引致的。請不要使用 noexec 重新掛載,並"
++"再次進行升級。"
++
++#: ../DistUpgrade/DistUpgradeFetcherCore.py:307
++#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:307
++#, python-format
++msgid "The error message is '%s'."
++msgstr "錯誤訊息 '%s'。"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:93
++msgid ""
++"Please report this as a bug and include the files /var/log/dist-upgrade/main."
++"log and /var/log/dist-upgrade/apt.log in your report. The upgrade has "
++"aborted.\n"
++"Your original sources.list was saved in /etc/apt/sources.list.distUpgrade."
++msgstr ""
++"請回報此錯誤並將檔案 /var/log/dist-upgrade/main.log 與 /var/log/dist-upgrade/"
++"apt.log 附在您的報告中。升級程序已取消。\n"
++"您原先的 sources.list 儲存於 /etc/apt/sources.list.distUpgrade。"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:117
++msgid "Aborting"
++msgstr "正在中止"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:122
++msgid "Demoted:\n"
++msgstr "降級:\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:129
++msgid "To continue please press [ENTER]"
++msgstr "若要繼續請按 [ENTER]"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:157
++#: ../DistUpgrade/DistUpgradeViewText.py:196
++#: ../DistUpgrade/DistUpgradeViewText.py:203
++msgid "Continue [yN] "
++msgstr "繼續 [yN] "
++
++#: ../DistUpgrade/DistUpgradeViewText.py:157
++#: ../DistUpgrade/DistUpgradeViewText.py:196
++msgid "Details [d]"
++msgstr "詳情 [d]"
++
++#. TRANSLATORS: the "y" is "yes"
++#. TRANSLATORS: first letter of a positive (yes) answer
++#: ../DistUpgrade/DistUpgradeViewText.py:162
++#: ../DistUpgrade/DistUpgradeViewText.py:206
++msgid "y"
++msgstr "y"
++
++#. TRANSLATORS: the "n" is "no"
++#. TRANSLATORS: first letter of a negative (no) answer
++#: ../DistUpgrade/DistUpgradeViewText.py:165
++#: ../DistUpgrade/DistUpgradeViewText.py:213
++msgid "n"
++msgstr "n"
++
++#. TRANSLATORS: the "d" is "details"
++#: ../DistUpgrade/DistUpgradeViewText.py:168
++msgid "d"
++msgstr "d"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:173
++#, python-format
++msgid "No longer supported: %s\n"
++msgstr "不再支援:%s\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:178
++#, python-format
++msgid "Remove: %s\n"
++msgstr "移除: %s\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:188
++#, python-format
++msgid "Install: %s\n"
++msgstr "安裝: %s\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:193
++#, python-format
++msgid "Upgrade: %s\n"
++msgstr "升級: %s\n"
++
++#: ../DistUpgrade/DistUpgradeViewText.py:210
++msgid "Continue [Yn] "
++msgstr "繼續 [Yn] "
++
++#: ../DistUpgrade/DistUpgradeViewText.py:231
++msgid ""
++"To finish the upgrade, a restart is required.\n"
++"If you select 'y' the system will be restarted."
++msgstr ""
++"需要重新開機才能完成升級。\n"
++"如果您選擇「y」系統將會重新開機。"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:1
++msgid "_Cancel Upgrade"
++msgstr "取消升級(_C)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:2
++msgid "_Resume Upgrade"
++msgstr "繼續升級(_R)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:3
++msgid ""
++"<b><big>Cancel the running upgrade?</big></b>\n"
++"\n"
++"The system could be in an unusable state if you cancel the upgrade. You are "
++"strongly adviced to resume the upgrade."
++msgstr ""
++"<b><big>是否取消正執行的升級?</big></b>\n"
++"\n"
++"如果取消升級可能會導致系統不穩定。強烈建議您繼續升級。"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:6
++msgid "_Start Upgrade"
++msgstr "開始升級(_S)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:9
++msgid "_Replace"
++msgstr "取代(_R)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:10
++msgid "Difference between the files"
++msgstr "檔案間的差別"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:11
++msgid "_Report Bug"
++msgstr "回報錯誤(_R)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:12
++msgid "_Continue"
++msgstr "繼續(_C)"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:13
++msgid "<b><big>Start the upgrade?</big></b>"
++msgstr "<b><big>開始升級嗎?</big></b>"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:15
++msgid ""
++"<b><big>Restart the system to complete the upgrade</big></b>\n"
++"\n"
++"Please save your work before continuing."
++msgstr ""
++"<b><big>重新啟動系統以完成升級</big></b>\n"
++"\n"
++"請在繼續前先儲存您的作業。"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:18
++msgid "Distribution Upgrade"
++msgstr "發行版升級"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:19
++#, fuzzy
++msgid "<b><big>Upgrading Ubuntu to version 12.10</big></b>"
++msgstr "<b><big>將 Ubuntu 升級至 11.10 版</big></b>"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:20
++msgid "    "
++msgstr "    "
++
++#: ../DistUpgrade/DistUpgrade.ui.h:22
++msgid "Setting new software channels"
++msgstr "設定新軟體頻道"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:24
++msgid "Restarting the computer"
++msgstr "重新啟動系統"
++
++#: ../DistUpgrade/DistUpgrade.ui.h:27
++msgid "Terminal"
++msgstr "終端"
++
++#: ../UpdateManager/backend/InstallBackendSynaptic.py:64
++msgid "Please wait, this can take some time."
++msgstr "請稍候,這需要一點時間。"
++
++#: ../UpdateManager/backend/InstallBackendSynaptic.py:66
++msgid "Update is complete"
++msgstr "更新完成"
++
++#: ../UpdateManager/DistUpgradeFetcher.py:114
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:109
++msgid "Could not find the release notes"
++msgstr "找不到發行公告"
++
++#: ../UpdateManager/DistUpgradeFetcher.py:115
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:110
++msgid "The server may be overloaded. "
++msgstr "伺服器可能負荷過重。 "
++
++#: ../UpdateManager/DistUpgradeFetcher.py:125
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:114
++msgid "Could not download the release notes"
++msgstr "無法下載發行公告"
++
++#: ../UpdateManager/DistUpgradeFetcher.py:126
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:115
++msgid "Please check your internet connection."
++msgstr "請檢查您的網際網路連線。"
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:68
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:91
++msgid "Upgrade"
++msgstr "升級"
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:95
++#: ../data/gtkbuilder/UpdateManager.ui.h:20
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:2
++msgid "Release Notes"
++msgstr "發行公告"
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:134
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:148
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:150
++msgid "Downloading additional package files..."
++msgstr "正在下載額外的套件檔案..."
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:148
++#, python-format
++msgid "File %s of %s at %sB/s"
++msgstr "檔案 %s / %s (速度:%s 位元組/秒)"
++
++#: ../UpdateManager/DistUpgradeFetcherKDE.py:150
++#, python-format
++msgid "File %s of %s"
++msgstr "檔案 %s / %s"
++
++#: ../UpdateManager/ChangelogViewer.py:75
++msgid "Open Link in Browser"
++msgstr "用瀏覽器開啟連結"
++
++#: ../UpdateManager/ChangelogViewer.py:78
++msgid "Copy Link to Clipboard"
++msgstr "複製連結至剪貼簿"
++
++#: ../UpdateManager/GtkProgress.py:162
++#, python-format
++msgid "Downloading file %(current)li of %(total)li with %(speed)s/s"
++msgstr "共 %(total)li 個檔案,正下載第 %(current)li 個 (速度: %(speed)s/秒)"
++
++#: ../UpdateManager/GtkProgress.py:167
++#, python-format
++msgid "Downloading file %(current)li of %(total)li"
++msgstr "共 %(total)li 個檔案,正下載第 %(current)li 個"
++
++#: ../UpdateManager/UpdateManager.py:106 ../do-release-upgrade:100
++msgid "Your Ubuntu release is not supported anymore."
++msgstr "您的 Ubuntu 發行版本已經不再支援。"
++
++#: ../UpdateManager/UpdateManager.py:107
++msgid ""
++"You will not get any further security fixes or critical updates. Please "
++"upgrade to a later version of Ubuntu."
++msgstr "您將無法再取得安全性修正或重大更新。請升級至較新版本的 Ubuntu。"
++
++#: ../UpdateManager/UpdateManager.py:115
++msgid "Upgrade information"
++msgstr "升級資訊"
++
++#: ../UpdateManager/UpdateManager.py:233
++#: ../UpdateManagerText/UpdateManagerText.py:35
++msgid "Install"
++msgstr "安裝"
++
++#: ../UpdateManager/UpdateManager.py:235
++msgid "Name"
++msgstr "名稱"
++
++#. upload_archive = version_match.group(2).strip()
++#: ../UpdateManager/UpdateManager.py:395
++#, python-format
++msgid "Version %s: \n"
++msgstr "版本 %s: \n"
++
++#: ../UpdateManager/UpdateManager.py:453
++msgid ""
++"No network connection detected, you can not download changelog information."
++msgstr "未偵測到網路連線,您無法下載更動紀錄資訊。"
++
++#: ../UpdateManager/UpdateManager.py:463
++msgid "Downloading list of changes..."
++msgstr "正下載更動清單..."
++
++#: ../UpdateManager/UpdateManager.py:507
++msgid "_Deselect All"
++msgstr "全部不選(_D)"
++
++#: ../UpdateManager/UpdateManager.py:513
++msgid "Select _All"
++msgstr "全部選取(_A)"
++
++#: ../UpdateManager/UpdateManager.py:572
++#, python-format
++msgid "%s will be downloaded."
++msgstr "將下載 %s。"
++
++#: ../UpdateManager/UpdateManager.py:584
++#, fuzzy
++msgid "The update has already been downloaded."
++msgid_plural "The updates have already been downloaded."
++msgstr[0] "更新已經下載,但尚未安裝。"
++
++#: ../UpdateManager/UpdateManager.py:589
++msgid "There are no updates to install."
++msgstr "沒有要安裝的更新。"
++
++#: ../UpdateManager/UpdateManager.py:598
++msgid "Unknown download size."
++msgstr "未知下載大小。"
++
++#: ../UpdateManager/UpdateManager.py:624
++msgid ""
++"It is unknown when the package information was updated last. Please click "
++"the 'Check' button to update the information."
++msgstr "未知套件資訊的上次更新時間。請點擊「檢查」按鈕來更新資訊。"
++
++#: ../UpdateManager/UpdateManager.py:630
++#, python-format
++msgid ""
++"The package information was last updated %(days_ago)s days ago.\n"
++"Press the 'Check' button below to check for new software updates."
++msgstr ""
++"%(days_ago)s 天前更新過套件資訊。\n"
++"請按下方「檢查」鈕看看有否新資訊。"
++
++#: ../UpdateManager/UpdateManager.py:635
++#, python-format
++msgid "The package information was last updated %(days_ago)s day ago."
++msgid_plural "The package information was last updated %(days_ago)s days ago."
++msgstr[0] "%(days_ago)s 天前更新過套件資訊。"
++
++#: ../UpdateManager/UpdateManager.py:639
++#, python-format
++msgid "The package information was last updated %(hours_ago)s hour ago."
++msgid_plural ""
++"The package information was last updated %(hours_ago)s hours ago."
++msgstr[0] "%(hours_ago)s 小時前更新過套件資訊。"
++
++#. TRANSLATORS: only in plural form, as %s minutes ago is one of 15, 30, 45 minutes ago
++#: ../UpdateManager/UpdateManager.py:644 ../UpdateManager/UpdateManager.py:646
++#: ../UpdateManager/UpdateManager.py:648
++#, python-format
++msgid "The package information was last updated about %s minutes ago."
++msgstr "套件資訊約 %s 分鐘前更新。"
++
++#: ../UpdateManager/UpdateManager.py:650
++msgid "The package information was just updated."
++msgstr "套件資訊剛更新。"
++
++#: ../UpdateManager/UpdateManager.py:689
++msgid "Software updates may be available for your computer."
++msgstr "可能有軟體更新提供予閣下之電腦。"
++
++#: ../UpdateManager/UpdateManager.py:697
++#, python-format
++msgid ""
++"Updated software has been issued since %s was released. Do you want to "
++"install it now?"
++msgstr ""
++
++#: ../UpdateManager/UpdateManager.py:700
++msgid ""
++"Updated software is available for this computer. Do you want to install it "
++"now?"
++msgstr ""
++
++#: ../UpdateManager/UpdateManager.py:758
++#, python-format
++msgid ""
++"The upgrade needs a total of %s free space on disk '%s'. Please free at "
++"least an additional %s of disk space on '%s'. Empty your trash and remove "
++"temporary packages of former installations using 'sudo apt-get clean'."
++msgstr ""
++"升級工作需要總共 %s 可用空間於硬碟 ‘%s’。請額外空出最少 %s 的空間於 ‘%s’。清"
++"理清理您的回收筒或使用 ‘sudo apt-get clean’ 移除上次安裝的暫存套件。"
++
++#: ../UpdateManager/UpdateManager.py:783
++msgid ""
++"The computer needs to restart to finish installing updates. Please save your "
++"work before continuing."
++msgstr "必須重啟電腦以完成安裝更新。繼續前請先儲存工作。"
++
++#: ../UpdateManager/UpdateManager.py:847
++msgid "Reading package information"
++msgstr "正在讀取套件資訊"
++
++#: ../UpdateManager/UpdateManager.py:862
++msgid "Connecting..."
++msgstr "連線中..."
++
++#: ../UpdateManager/UpdateManager.py:879
++msgid "You may not be able to check for updates or download new updates."
++msgstr "您可能無法檢查是否有更新,或是下載新的更新。"
++
++#: ../UpdateManager/UpdateManager.py:1002
++msgid "Could not initialize the package information"
++msgstr "無法初始化套件資訊"
++
++#: ../UpdateManager/UpdateManager.py:1003
++msgid ""
++"An unresolvable problem occurred while initializing the package "
++"information.\n"
++"\n"
++"Please report this bug against the 'update-manager' package and include the "
++"following error message:\n"
++msgstr ""
++"初始套件資訊時發生不能解決的問題。\n"
++"\n"
++"請匯報此為『update-manager』套件的問題並附上以下的錯誤訊息:\n"
++
++#: ../UpdateManager/UpdateManager.py:1032
++msgid ""
++"An unresolvable problem occurred while calculating the upgrade.\n"
++"\n"
++"Please report this bug against the 'update-manager' package and include the "
++"following error message:"
++msgstr ""
++"計算升級時發生不能解決的問題。\n"
++"\n"
++"請匯報此為『update-manager』套件的問題並附上以下的錯誤訊息:"
++
++#: ../UpdateManager/UpdateManager.py:1056
++msgid " (New install)"
++msgstr " (新安裝)"
++
++#. TRANSLATORS: the b stands for Bytes
++#: ../UpdateManager/UpdateManager.py:1063
++#, python-format
++msgid "(Size: %s)"
++msgstr "(大小:%s)"
++
++#: ../UpdateManager/UpdateManager.py:1067
++#, python-format
++msgid "From version %(old_version)s to %(new_version)s"
++msgstr "由版本 %(old_version)s 更新至 %(new_version)s"
++
++#: ../UpdateManager/UpdateManager.py:1071
++#, python-format
++msgid "Version %s"
++msgstr "版本 %s"
++
++#: ../UpdateManager/UpdateManager.py:1104 ../do-release-upgrade:112
++msgid "Release upgrade not possible right now"
++msgstr "目前不能升級發行版"
++
++#: ../UpdateManager/UpdateManager.py:1105 ../do-release-upgrade:113
++#, c-format, python-format
++msgid ""
++"The release upgrade can not be performed currently, please try again later. "
++"The server reported: '%s'"
++msgstr "發行版升級升級目前無法執行,請稍後重試。該伺服器回報:「%s」。"
++
++#: ../UpdateManager/UpdateManager.py:1107 ../check-new-release-gtk:126
++msgid "Downloading the release upgrade tool"
++msgstr "正下載發行版更新工具"
++
++#: ../UpdateManager/UpdateManager.py:1114
++#, python-format
++msgid "<b>New Ubuntu release '%s' is available</b>"
++msgstr "<b>有新 Ubuntu 發行版 '%s' 可供升級</b>"
++
++#. we assert a clean cache
++#: ../UpdateManager/UpdateManager.py:1153
++msgid "Software index is broken"
++msgstr "軟體索引損壞"
++
++#: ../UpdateManager/UpdateManager.py:1154
++msgid ""
++"It is impossible to install or remove any software. Please use the package "
++"manager \"Synaptic\" or run \"sudo apt-get install -f\" in a terminal to fix "
++"this issue at first."
++msgstr ""
++"無法安裝或移除軟體。請先用 Synaptic 套件管理員或在終端機執行「sudo apt-get "
++"install -f」修正。"
++
++#: ../UpdateManager/UnitySupport.py:57
++msgid "Check for Updates"
++msgstr "檢查更新"
++
++#: ../UpdateManager/UnitySupport.py:66
++msgid "Install All Available Updates"
++msgstr "安裝所有可進行的更新"
++
++#: ../UpdateManagerText/UpdateManagerText.py:34
++msgid "Cancel"
++msgstr "取消"
++
++#: ../UpdateManagerText/UpdateManagerText.py:37
++msgid "Changelog"
++msgstr "變更記錄"
++
++#: ../UpdateManagerText/UpdateManagerText.py:40
++msgid "Updates"
++msgstr "更新"
++
++#: ../UpdateManagerText/UpdateManagerText.py:53
++msgid "Building Updates List"
++msgstr "正建立更新清單"
++
++#: ../UpdateManagerText/UpdateManagerText.py:56
++msgid ""
++"\n"
++"A normal upgrade can not be calculated, please run: \n"
++"  sudo apt-get dist-upgrade\n"
++"\n"
++"\n"
++"This can be caused by:\n"
++" * A previous upgrade which didn't complete\n"
++" * Problems with some of the installed software\n"
++" * Unofficial software packages not provided by Ubuntu\n"
++" * Normal changes of a pre-release version of Ubuntu"
++msgstr ""
++"\n"
++"無法計算標準升級,請執行: \n"
++"  sudo apt-get dist-upgrade\n"
++"\n"
++"\n"
++" 這可能由以下原因造成:\n"
++" * 前次升級程序未完成\n"
++" * 某些已安裝的軟體有問題\n"
++" * 安裝了非由 Ubuntu 官方提供的軟體套件\n"
++" * Ubuntu 非正式發佈版本的正常更動"
++
++#: ../UpdateManagerText/UpdateManagerText.py:125
++msgid "Downloading changelog"
++msgstr "正下載變更記錄"
++
++#: ../UpdateManager/Core/MyCache.py:147
++#, python-format
++msgid "Other updates (%s)"
++msgstr "其他更新 (%s)"
++
++#: ../UpdateManager/Core/MyCache.py:325
++msgid "This update does not come from a source that supports changelogs."
++msgstr "這份更新的來源不支援變更記錄 (changelog)。"
++
++#: ../UpdateManager/Core/MyCache.py:331 ../UpdateManager/Core/MyCache.py:359
++msgid ""
++"Failed to download the list of changes. \n"
++"Please check your Internet connection."
++msgstr ""
++"下載更動清單失敗。\n"
++"請檢查網際網路連線。"
++
++#: ../UpdateManager/Core/MyCache.py:338
++#, python-format
++msgid ""
++"Changes for the versions:\n"
++"Installed version: %s\n"
++"Available version: %s\n"
++"\n"
++msgstr ""
++"版本的更動情況:\n"
++"已安裝版本:%s\n"
++"可用的版本:%s\n"
++"\n"
++
++#: ../UpdateManager/Core/MyCache.py:348
++#, python-format
++msgid ""
++"The changelog does not contain any relevant changes.\n"
++"\n"
++"Please use http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n"
++"until the changes become available or try again later."
++msgstr ""
++"變更記錄並未包含相關更動。\n"
++"\n"
++"有變更記錄提供前請至 http://launchpad.net/ubuntu/+source/%s/%s/+changelog,\n"
++"或稍候再試。"
++
++#: ../UpdateManager/Core/MyCache.py:353
++#, python-format
++msgid ""
++"The list of changes is not available yet.\n"
++"\n"
++"Please use http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n"
++"until the changes become available or try again later."
++msgstr ""
++"仍未有更動清單。\n"
++"\n"
++"有更動清單提供前請至 http://launchpad.net/ubuntu/+source/%s/%s/+changelog,\n"
++"或稍候再試。"
++
++#: ../UpdateManager/Core/UpdateList.py:51
++msgid "Failed to detect distribution"
++msgstr "無法偵測出版本"
++
++#: ../UpdateManager/Core/UpdateList.py:52
++#, python-format
++msgid "A error '%s' occurred while checking what system you are using."
++msgstr "當檢查您所使用的系統時有錯誤 \"%s\" 發生。"
++
++#: ../UpdateManager/Core/UpdateList.py:63
++msgid "Important security updates"
++msgstr "重要的安全性更新"
++
++#: ../UpdateManager/Core/UpdateList.py:64
++msgid "Recommended updates"
++msgstr "推薦更新"
++
++#: ../UpdateManager/Core/UpdateList.py:65
++msgid "Proposed updates"
++msgstr "建議更新"
++
++#: ../UpdateManager/Core/UpdateList.py:66
++msgid "Backports"
++msgstr "回殖套件 (Backports)"
++
++#: ../UpdateManager/Core/UpdateList.py:67
++msgid "Distribution updates"
++msgstr "發行版更新"
++
++#: ../UpdateManager/Core/UpdateList.py:72
++msgid "Other updates"
++msgstr "其他更新"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:1
++#, fuzzy
++msgid "<big><b>Starting Software Updater</b></big>"
++msgstr "<big><b>啟動更新管理員</b></big>"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:2
++msgid ""
++"Software updates correct errors, eliminate security vulnerabilities and "
++"provide new features."
++msgstr "軟體更新會修正錯誤、消除安全隱患並提供新功能。"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:3
++msgid "_Partial Upgrade"
++msgstr "部份升級(_P)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:4
++msgid "<big><b>Not all updates can be installed</b></big>"
++msgstr "<big><b>並非所有更新都可安裝</b></big>"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:5
++msgid ""
++"Run a partial upgrade, to install as many updates as possible. \n"
++"\n"
++"This can be caused by:\n"
++" * A previous upgrade which didn't complete\n"
++" * Problems with some of the installed software\n"
++" * Unofficial software packages not provided by Ubuntu\n"
++" * Normal changes of a pre-release version of Ubuntu"
++msgstr ""
++"執行部份升級,將儘可能安裝最多的更新。 \n"
++" 這可能由以下原因造成:\n"
++" * 前次升級程序未完成\n"
++" * 某些已安裝的軟體有問題\n"
++" * 安裝了非由 Ubuntu 官方提供的軟體套件\n"
++" * Ubuntu 非正式發佈版本的正常更動"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:12
++msgid "Chec_k"
++msgstr "檢查(_K)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:13
++msgid ""
++"<b><big>You must check for updates manually</big></b>\n"
++"\n"
++"Your system does not check for updates automatically. You can configure this "
++"behavior in <i>Software Sources</i> on the <i>Updates</i> tab."
++msgstr ""
++"<b><big>您必須手動檢查更新</big></b>\n"
++"\n"
++"您的系統不會自動檢查更新。您可以 <i>更新</i> 分頁之 <i>軟體來源</i> 設定。"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:16
++msgid "_Hide this information in the future"
++msgstr "以後不要再顯示此訊息(_H)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:17
++msgid "Co_ntinue"
++msgstr "繼續(_N)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:18
++msgid "<big><b>Running on battery</b></big>"
++msgstr "<big><b>使用電池運行</b></big>"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:19
++msgid "Your system is running on battery. Are you sure you want to continue?"
++msgstr "您的系統正在使用電池。確定要繼續嗎?"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:21
++msgid "_Upgrade"
++msgstr "升級(_U)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:22
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:8
++msgid "Show progress of individual files"
++msgstr "顯示單一檔案的進度"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:23
++#: ../data/update-manager.desktop.in.h:1
++#, fuzzy
++msgid "Software Updater"
++msgstr "軟體更新"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:24
++#, fuzzy
++msgid "Starting Software Updater"
++msgstr "軟體更新"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:25
++msgid "U_pgrade"
++msgstr "升級(_P)"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:27
++msgid "updates"
++msgstr "更新"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:28
++msgid "Changes"
++msgstr "變更"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:29
++msgid "Description"
++msgstr "說明"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:30
++#, fuzzy
++msgid "Details of updates"
++msgstr "更新說明"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:31
++msgid ""
++"You are connected via roaming and may be charged for the data consumed by "
++"this update."
++msgstr "您已透過漫遊連上網路,可能要對本次更新所下載的資料量付費。"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:32
++msgid ""
++"You may want to wait until you’re not using a mobile broadband connection."
++msgstr ""
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:33
++msgid "It’s safer to connect the computer to AC power before updating."
++msgstr "在更新前先將電腦接上 AC 電源比較安全。"
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:34
++msgid "_Settings..."
++msgstr "設定(_S)..."
++
++#: ../data/gtkbuilder/UpdateManager.ui.h:35
++#, fuzzy
++msgid "_Install Now"
++msgstr "安裝"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:1
++msgid "<b>A new version of Ubuntu is available. Would you like to upgrade?</b>"
++msgstr "<b>有新版本 Ubuntu。要否升級?</b>"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:3
++msgid "Don't Upgrade"
++msgstr "不升級"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:4
++msgid "Ask Me Later"
++msgstr "稍後再問我"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:5
++msgid "Yes, Upgrade Now"
++msgstr "是,現在升級"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:6
++msgid "You have declined to upgrade to the new Ubuntu"
++msgstr "您已拒絕升級至新的 Ubuntu"
++
++#: ../data/gtkbuilder/UpgradePromptDialog.ui.h:7
++#, fuzzy
++msgid ""
++"You can upgrade at a later time by opening Software Updater and click on "
++"\"Upgrade\"."
++msgstr "您稍後仍可以透過開啟更新管理員並按下『升級』進行升級。"
++
++#: ../data/update-manager.desktop.in.h:2
++msgid "Software Updates"
++msgstr "軟體更新"
++
++#: ../data/update-manager.desktop.in.h:3
++msgid "Show and install available updates"
++msgstr "顯示並安裝現有軟體更新"
++
++#: ../update-manager:66 ../update-manager-text:55 ../do-release-upgrade:51
++msgid "Show version and exit"
++msgstr "顯示版本後結束"
++
++#: ../update-manager:69
++msgid "Directory that contains the data files"
++msgstr "含有資料檔案的目錄"
++
++#: ../update-manager:72
++msgid "Check if a new Ubuntu release is available"
++msgstr "檢查有否新 Ubuntu 發行版可供升級"
++
++#: ../update-manager:75 ../do-release-upgrade:54 ../check-new-release-gtk:186
++msgid "Check if upgrading to the latest devel release is possible"
++msgstr "檢查能否升級至最新開發發行版"
++
++#: ../update-manager:79
++msgid "Upgrade using the latest proposed version of the release upgrader"
++msgstr "使用最新建議版本的發行升級工具升級"
++
++#: ../update-manager:86
++msgid "Do not focus on map when starting"
++msgstr "啟動時不預先選取圖錄"
++
++#: ../update-manager:89
++msgid "Try to run a dist-upgrade"
++msgstr "試著執行 dist-upgrade"
++
++#: ../update-manager:92
++msgid "Do not check for updates when starting"
++msgstr "當啟動時不要檢查更新"
++
++#: ../update-manager:96 ../do-release-upgrade:70
++msgid "Test upgrade with a sandbox aufs overlay"
++msgstr "使用沙堆 aufs 層測試升級"
++
++#: ../update-manager:116
++msgid "Running partial upgrade"
++msgstr "執行部份升級"
++
++#: ../update-manager-text:59
++msgid "Show description of the package instead of the changelog"
++msgstr "顯示套件描述而不是變更紀錄"
++
++#: ../do-release-upgrade:58 ../check-new-release-gtk:190
++msgid ""
++"Try upgrading to the latest release using the upgrader from $distro-proposed"
++msgstr "試著使用 $distro-proposed 的套件升級程式來升級到最新的發行版本"
++
++#: ../do-release-upgrade:62
++msgid ""
++"Run in a special upgrade mode.\n"
++"Currently 'desktop' for regular upgrades of a desktop system and 'server' "
++"for server systems are supported."
++msgstr ""
++"在特殊升級模式執行。\n"
++"目前只支援以 'desktop' 模式升級桌面版本的系統,以及以 'server' 模式升級伺服器"
++"版的系統。"
++
++#: ../do-release-upgrade:68
++msgid "Run the specified frontend"
++msgstr "執行指定的前端"
++
++#: ../do-release-upgrade:73
++msgid ""
++"Check only if a new distribution release is available and report the result "
++"via the exit code"
++msgstr "檢查有否新發行版並以結束碼報告結果"
++
++#: ../do-release-upgrade:87
++msgid "Checking for a new Ubuntu release"
++msgstr "檢查是否有新的 Ubuntu 發行"
++
++#: ../do-release-upgrade:101
++msgid ""
++"For upgrade information, please visit:\n"
++"%(url)s\n"
++msgstr ""
++"若要取得升級資訊,請參訪:\n"
++"%(url)s\n"
++
++#: ../do-release-upgrade:107
++msgid "No new release found"
++msgstr "沒找到新發行版"
++
++#: ../do-release-upgrade:119
++#, c-format
++msgid "New release '%s' available."
++msgstr "有新版「%s」提供。"
++
++#: ../do-release-upgrade:120
++msgid "Run 'do-release-upgrade' to upgrade to it."
++msgstr "執行 ‘do-release-upgrade’ 進行升級工作。"
++
++#: ../check-new-release-gtk:101
++msgid "Ubuntu %(version)s Upgrade Available"
++msgstr "可以升級至 Ubuntu %(version)s"
++
++#: ../check-new-release-gtk:143
++#, c-format
++msgid "You have declined the upgrade to Ubuntu %s"
++msgstr "您已拒絕升級至 Ubuntu %s"
++
++#: ../check-new-release-gtk:196
++msgid "Add debug output"
++msgstr "加入除錯輸出"
++
++#: ../ubuntu-support-status:91
++msgid "Show unsupported packages on this machine"
++msgstr "顯示此機器上不再支援的套件"
++
++#: ../ubuntu-support-status:94
++msgid "Show supported packages on this machine"
++msgstr "顯示此機器上受支援的套件"
++
++#: ../ubuntu-support-status:97
++msgid "Show all packages with their status"
++msgstr "顯示所有套件及其狀態"
++
++#: ../ubuntu-support-status:100
++msgid "Show all packages in a list"
++msgstr "將所有套件以清單顯示"
++
++#: ../ubuntu-support-status:142
++#, c-format
++msgid "Support status summary of '%s':"
++msgstr "「%s」的支援狀態摘要:"
++
++#: ../ubuntu-support-status:145
++msgid "You have %(num)s packages (%(percent).1f%%) supported until %(time)s"
++msgstr "您現在有 %(num)s 個套件 (%(percent).1f%%) 將支援直到 %(time)s"
++
++#: ../ubuntu-support-status:151
++msgid ""
++"You have %(num)s packages (%(percent).1f%%) that can not/no-longer be "
++"downloaded"
++msgstr "您有 %(num)s 個套件 (%(percent).1f%%) 無法/不再能下載"
++
++#: ../ubuntu-support-status:154
++msgid "You have %(num)s packages (%(percent).1f%%) that are unsupported"
++msgstr "您有 %(num)s 個套件 (%(percent).1f%%) 不再支援"
++
++#: ../ubuntu-support-status:162
++msgid ""
++"Run with --show-unsupported, --show-supported or --show-all to see more "
++"details"
++msgstr ""
++"加上 --show-unsupported、--show-supported 或是 --show-all 作為參數執行以查看"
++"更多細節"
++
++#: ../ubuntu-support-status:166
++msgid "No longer downloadable:"
++msgstr "不再能下載:"
++
++#: ../ubuntu-support-status:169
++msgid "Unsupported: "
++msgstr "不再支援: "
++
++#: ../ubuntu-support-status:174
++#, c-format
++msgid "Supported until %s:"
++msgstr "支援直至 %s:"
++
++#: ../ubuntu-support-status:183
++msgid "Unsupported"
++msgstr "不再支援"
++
++#. Why do we use %s here instead of $strings or {} format placeholders?
++#. It's because we don't want to break existing translations.
++#: ../janitor/plugincore/exceptions.py:42
++#, python-format
++msgid "Unimplemented method: %s"
++msgstr "未實作的方法: %s"
++
++#: ../janitor/plugincore/core/file_cruft.py:41
++msgid "A file on disk"
++msgstr "磁碟上之檔案"
++
++#: ../janitor/plugincore/core/missing_package_cruft.py:39
++msgid "Install missing package."
++msgstr "安裝缺少的套件。"
++
++#. 2012-06-08 BAW: i18n string; don't use {} or PEP 292.
++#: ../janitor/plugincore/core/missing_package_cruft.py:49
++#, python-format
++msgid "Package %s should be installed."
++msgstr "應安裝 %s 套件。"
++
++#: ../janitor/plugincore/core/package_cruft.py:49
++msgid ".deb package"
++msgstr ".deb 套件"
++
++#: ../janitor/plugincore/plugins/langpack_manual_plugin.py:46
++#, python-format
++msgid "%s needs to be marked as manually installed."
++msgstr "%s 要標記為手動安裝。"
++
++#: ../janitor/plugincore/plugins/kdelibs4to5_plugin.py:49
++msgid ""
++"When upgrading, if kdelibs4-dev is installed, kdelibs5-dev needs to be "
++"installed. See bugs.launchpad.net, bug #279621 for details."
++msgstr ""
++"在升級時,如果有安裝 kdelibs4-dev,那 kdelibs5-dev 就必須安裝。詳情請見 bugs."
++"launchpad.net, bug #279621。"
++
++#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:44
++#, python-format
++msgid "%i obsolete entries in the status file"
++msgstr "狀態檔有 %i 個廢棄條目"
++
++#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:47
++msgid "Obsolete entries in dpkg status"
++msgstr "dpkg 狀態中之廢棄條目"
++
++#. pragma: no cover
++#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:50
++msgid "Obsolete dpkg status entries"
++msgstr "廢棄的 dpkg 狀態條目"
++
++#: ../janitor/plugincore/plugins/remove_lilo_plugin.py:42
++msgid "Remove lilo since grub is also installed.(See bug #314004 for details.)"
++msgstr "因已安裝 grub,移除 lilo。(詳情見 bug #314004。)"
++
++#~ msgid ""
++#~ "After your package information was updated the essential package '%s' can "
++#~ "not be found anymore so a bug reporting process is being started."
++#~ msgstr ""
++#~ "在您的套件資訊更新之後,我們無法再找到必要的「%s」套件,因此正在啟動臭蟲回"
++#~ "報程序。"
++
++#~ msgid "<b><big>Upgrading Ubuntu to version 12.04</big></b>"
++#~ msgstr "<b><big>升級 Ubuntu 至 12.04 版</big></b>"
++
++#~ msgid "%(count)s update has been selected."
++#~ msgid_plural "%(count)s updates have been selected."
++#~ msgstr[0] "已選取 %(count)s 項更新。"
++
++#~ msgid "%(count_str)s %(download_str)s"
++#~ msgstr "%(count_str)s %(download_str)s"
++
++#~ msgid "Welcome to Ubuntu"
++#~ msgstr "歡迎使用 Ubuntu"
++
++#~ msgid ""
++#~ "These software updates have been issued since this version of Ubuntu was "
++#~ "released."
++#~ msgstr "自從這個版本的 Ubuntu 發行後,已經釋出這些軟體更新"
++
++#~ msgid "Software updates are available for this computer."
++#~ msgstr "有此電腦可用的軟體更新。"
++
++#~ msgid "Update Manager"
++#~ msgstr "更新管理員"
++
++#~ msgid "Starting Update Manager"
++#~ msgstr "正在啟動更新管理員"
++
++#~ msgid "You are connected via a wireless modem."
++#~ msgstr "您正透過無線數據機連線。"
++
++#~ msgid "_Install Updates"
++#~ msgstr "安裝更新套件(_I)"
++
++#~ msgid "Checking for a new ubuntu release"
++#~ msgstr "檢查有沒有新的 ubuntu 發行版"
++
++#~ msgid "Your system is up-to-date"
++#~ msgstr "系統已經在最新狀態"
++
++#~ msgid ""
++#~ "This upgrade is running in sandbox (test) mode. All changes are written "
++#~ "to '%s' and will be lost on the next reboot.\n"
++#~ "\n"
++#~ "*No* changes written to a systemdir from now until the next reboot are "
++#~ "permanent."
++#~ msgstr ""
++#~ "這次升級是在沙堆(sandbox, 測試)模式中執行。所有更動都會寫入至「%s」並且會"
++#~ "在下次重新開機時消失。\n"
++#~ "\n"
++#~ "現在起到下次重新開機前將*不會*有任何變更寫入至系統目錄。"
++
++#~ msgid "The update has already been downloaded, but not installed"
++#~ msgid_plural "The updates have already been downloaded, but not installed"
++#~ msgstr[0] "更新已下載,但尚未安裝"
++
++#~ msgid ""
++#~ "Fetching and installing the upgrade can take several hours. Once the "
++#~ "download has finished, the process cannot be cancelled."
++#~ msgstr "下載和安裝升級會花上數小時。一旦下載完成,程序將不能取消。"
++
++#~ msgid "There are no updates to install"
++#~ msgstr "沒有要安裝的更新"
++
++#~ msgid "Software updates are available for this computer"
++#~ msgstr "有軟體更新提供予此電腦。"
++
++#~ msgid ""
++#~ "If you don't want to install them now, choose \"Update Manager\" from the "
++#~ "Administration menu later."
++#~ msgstr "若目前不想安裝,可稍後於管理選單開啟「更新管理員」。"
++
++#~ msgid ""
++#~ "If you don't want to install them now, choose \"Update Manager\" from "
++#~ "Applications later."
++#~ msgstr ""
++#~ "若現在您不想要安裝它們,您可以稍後從「應用程式」選擇「更新管理員」再安裝。"
++
++#~ msgid ""
++#~ "You will not get any further security fixes or critical updates. Please "
++#~ "upgrade to a later version of Ubuntu Linux."
++#~ msgstr "您將無法再取得安全性修正與重大更新。請升級至新版 Ubuntu Linux。"
++
++#~ msgid ""
++#~ "Upgrading the repository information resulted in a invalid file. Please "
++#~ "report this as a bug using the command 'ubuntu-bug update-manager' in a "
++#~ "terminal."
++#~ msgstr ""
++#~ "升級套件庫時導致無效的檔案。請在終端機內輸入指令「ubuntu-bug update-"
++#~ "manager」回報錯誤。"
++
++#~ msgid ""
++#~ "\n"
++#~ "\n"
++#~ "Please report this bug using the command 'ubuntu-bug update-manager' in a "
++#~ "terminal and include the files in /var/log/dist-upgrade/ in the bug "
++#~ "report.\n"
++#~ "%s"
++#~ msgstr ""
++#~ "\n"
++#~ "\n"
++#~ "請在終端機內輸入指令「ubuntu-bug update-manager」回報錯誤,並在錯誤報告中"
++#~ "附上 /var/log/dist-upgrade/ 內之檔案。\n"
++#~ "%s"
++
++#~ msgid ""
++#~ "The system was unable to get the prerequisites for the upgrade. The "
++#~ "upgrade will abort now and restore the original system state.\n"
++#~ "\n"
++#~ "Please report this as a bug using the command 'ubuntu-bug update-manager' "
++#~ "in a terminal and include the files in /var/log/dist-upgrade/ in the bug "
++#~ "report."
++#~ msgstr ""
++#~ "此系統無法達到升級之要求。現在將中斷升級並回復系統至原始狀態。\n"
++#~ "\n"
++#~ "請在終端機內輸入指令「ubuntu-bug update-manager」回報錯誤,並在錯誤報告中"
++#~ "附上 /var/log/dist-upgrade/ 內之檔案。"
++
++#~ msgid ""
++#~ "Preparing the system for the upgrade failed. Please report this using the "
++#~ "command 'ubuntu-bug update-manager' in a terminal and include the files "
++#~ "in /var/log/dist-upgrade/ in the bug report."
++#~ msgstr ""
++#~ "準備系統升級失敗。請在終端機內輸入指令「ubuntu-bug update-manager」回報錯"
++#~ "誤,並在錯誤報告中附上 /var/log/dist-upgrade/ 內之檔案。"
++
++#~ msgid ""
++#~ "After your package information was updated the essential package '%s' can "
++#~ "not be found anymore.\n"
++#~ "This indicates a serious error, please report this bug using the command "
++#~ "'ubuntu-bug update-manager' in a terminal and include the files in /var/"
++#~ "log/dist-upgrade/ in the bug report."
++#~ msgstr ""
++#~ "套件資訊更新後無法找到必要套件「%s」。\n"
++#~ "此為嚴重錯誤,請在終端機內輸入指令「ubuntu-bug update-manager」回報錯誤,"
++#~ "並在錯誤報告中附上 /var/log/dist-upgrade/ 內的檔案。"
++
++#~ msgid "Your graphics hardware may not be fully supported in Ubuntu 11.04."
++#~ msgstr "您的繪圖硬體可能無法在 Ubuntu 11.04 獲得完整的支援。"
++
++#~ msgid ""
++#~ "The support in Ubuntu 11.04 for your intel graphics hardware is limited "
++#~ "and you may encounter problems after the upgrade. Do you want to continue "
++#~ "with the upgrade?"
++#~ msgstr ""
++#~ "您的 Intel 繪圖硬體在 Ubuntu 11.04 內的支援有限,且可能會在升級之後碰到一"
++#~ "些問題。您要繼續進行升級嗎?"
++
++#~ msgid "%.0f kB"
++#~ msgstr "%.0f kB"
++
++#~ msgid "0 kB"
++#~ msgstr "0 kB"
++
++#~ msgid "1 kB"
++#~ msgstr "1 kB"
++
++#~ msgid ""
++#~ "These software updates have been issued since this version of Ubuntu was "
++#~ "released. If you don't want to install them now, choose \"Update Manager"
++#~ "\" from Applications later."
++#~ msgstr ""
++#~ "自從這個 Ubuntu 版本發行後已經發布這些軟體更新。如果您現在還不想安裝它們,"
++#~ "請稍後從「應用程式」選單選擇「更新管理員」。"
++
++#~ msgid ""
++#~ "These software updates have been issued since this version of Ubuntu was "
++#~ "released. If you don't want to install them now, choose \"Update Manager"
++#~ "\" from the Administration Menu later."
++#~ msgstr ""
++#~ "自從這個 Ubuntu 版本發行後已經發布這些軟體更新。如果您現在還不想安裝它們,"
++#~ "請稍後從「管理」選單選擇「更新管理員」。"
++
++
++msgid "Unable to access the source management server, 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 "其他任務正在更新升級中,請稍後再卸載。"
++
++#: ../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 "Application installation control policy not enabled ."
++msgstr "應用安裝管控未開啓."
++
++msgid "Installation failed! Application is not in the software whitelist list!"
++msgstr "安裝失敗!軟件包不在白名單列表!"
++
++msgid "Installation failed! Application is in the software blacklist list!"
++msgstr "安裝失敗!軟件包在黑名單列表!"
++
++msgid "Application installation in unknown mode ."
++msgstr "應用安裝管控策略未知."
++
++#: ../SystemUpdater/Core/utils.py:753
++msgid "Cancel authentication."
++msgstr "取消認證"
+diff --git a/backend-immutable/tests/report-updater-bug b/backend-immutable/tests/report-updater-bug
+new file mode 100755
+index 0000000..ef3bf05
+--- /dev/null
++++ b/backend-immutable/tests/report-updater-bug
+@@ -0,0 +1,62 @@
++#!/bin/sh
++#系统升级收集bug日志使用
++
++if [ $(id -u) -eq 0 ]; then
++    echo "当前执行权限是root,请使用普通权限来执行"
++    exit 1
++fi
++
++echo "系统升级收集BUG日志使用..."
++
++#建立收集的log目录
++mkdir updaterlog
++#记录一些基本信息
++date >> updaterlog/base-info
++dpkg -l | grep kylin-system-updater >> updaterlog/base-info
++echo $1 >> updaterlog/base-info
++echo "记录BUG产生时间(系统当前时间)以及升级相关的版本信息:"
++cat updaterlog/base-info
++
++cp /etc/apt/sources.list updaterlog || true
++cp -r /etc/apt/apt.conf.d updaterlog || true
++cp -r /var/log/syslog updaterlog || true
++cp -r /usr/share/kylin-update-desktop-config/config/ updaterlog || true
++cp -r /var/log/kylin-system-updater/ updaterlog || true
++
++#收集apt的日志
++cp -r /var/log/apt updaterlog || true
++cp -r /var/log/dpkg.log updaterlog || true
++cp -r /var/log/kylin-unattended-upgrades/ updaterlog || true
++cp -r ~/.config/kylin-background-upgrade/ updaterlog || true
++
++#激活
++cp -r ~/.log/kylin-activation/ updaterlog || true
++
++#收集前端日志
++cp -r ~/.log/kylin-update-frontend-notifysend.log updaterlog >/dev/null 2>&1 || true
++cp -r ~/.log/ukui-control-center.log updaterlog >/dev/null 2>&1 || true 
++cp -r ~/.log/ukui-notification-daemon.log updaterlog >/dev/null 2>&1 || true
++cp -r ~/.config/ukui-session/ updaterlog >/dev/null 2>&1 || true
++cp -r /tmp/kylin-updateresult-notify.log updaterlog >/dev/null 2>&1 || true
++
++outputName="$(date +%m-%d,%H-%M-%S)-updaterLog.tar.gz"
++
++#将所有的日志进行打包
++tar -czvf updaterLog.tar.gz updaterlog >/dev/null
++
++#删除收集的日志目录
++rm -rf updaterlog
++
++#将文件存储到桌面
++if [ ! -d ~/桌面 ]; then
++    mv updaterLog.tar.gz ~/Desktop/$outputName
++    echo 输出位置:~/Desktop/$outputName
++else
++    mv updaterLog.tar.gz ~/桌面/$outputName
++    echo 输出位置:~/桌面/$outputName
++fi
++
++echo "系统更新日志收集完毕..."
++echo "\033[1;31m注意:\033[0m 1、请确保Bug复现的时间与执行脚本收集日志时间相近,以此能根据脚本执行时间快速定位到问题的相关日志..."
++echo "       2、若Bug复现的时间与现在时间相差较远时,请手动输入大概复现时间。例如 report-updater-bug 月-日,时-分"
++echo "请将桌面下\033[5;32;49;1m $outputName \033[0m日志文件提交到禅道... "
+\ No newline at end of file
+diff --git a/backend-immutable/tests/setup.cfg b/backend-immutable/tests/setup.cfg
+new file mode 100644
+index 0000000..a9eefe5
+--- /dev/null
++++ b/backend-immutable/tests/setup.cfg
+@@ -0,0 +1,15 @@
++[build_i18n]
++domain=kylin-system-updater
++
++# xml_files=[("share/metainfo/",
++#          ("data/update-manager.appdata.xml.in",)),
++#               ]
++
++[sdist]
++formats = bztar
++
++[nosetests]
++match=test
++
++# [install]
++# skip-build=0
+diff --git a/backend-immutable/tests/setup.py b/backend-immutable/tests/setup.py
+new file mode 100755
+index 0000000..1824eb0
+--- /dev/null
++++ b/backend-immutable/tests/setup.py
+@@ -0,0 +1,21 @@
++#!/usr/bin/env python3
++# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
++from distutils.core import setup
++from DistUtilsExtra.command import (
++    build_extra, build_i18n, build_help)
++
++disabled = []
++class CustomBuild(build_extra.build_extra):
++    def run(self):
++        build_extra.build_extra.run(self)
++
++setup(
++    packages=[  'SystemUpdater',
++                'SystemUpdater.backend',
++                'SystemUpdater.Core'   
++    ],
++    cmdclass={  "build": CustomBuild,
++                "build_i18n": build_i18n.build_i18n
++                # "build_help": build_help.build_help
++    }
++)
+diff --git a/backend-immutable/tests/sqlite_tests.py b/backend-immutable/tests/sqlite_tests.py
+new file mode 100644
+index 0000000..4a429a2
+--- /dev/null
++++ b/backend-immutable/tests/sqlite_tests.py
+@@ -0,0 +1,13 @@
++from SystemUpdater.Core.Database import Sqlite3Server
++from SystemUpdater.Core.DataAcquisition import get_east_8_time
++
++class sqliteTests():
++    def __init__(self):
++        self.sqlite3_server = Sqlite3Server(self)
++    
++    def test_insert_into_display(self):
++        # insert: check_time
++        self.sqlite3_server.insert_into_display("check_time", get_east_8_time()[0:-4])
++
++if __name__ == "__main__":
++    sqliteTests().test_insert_into_display()
+diff --git a/backend-immutable/tests/test-configs.py b/backend-immutable/tests/test-configs.py
+new file mode 100644
+index 0000000..f6ae998
+--- /dev/null
++++ b/backend-immutable/tests/test-configs.py
+@@ -0,0 +1,86 @@
++import json
++from SystemUpdater.configs import JSONConfig
++
++configs_file = "/tmp/configs1.json"
++configs2_file = "/tmp/configs2.json"
++
++test_data = {
++    "name": "Alice",
++    "age": 20,
++    "local": {
++        "pre": {
++            "en": "wwwww"
++        }
++    }
++}
++
++def save(save_file,data):
++    with open(save_file, 'w') as f:
++        json.dump(data, f, indent=4)
++
++def test_read_config():
++    save(configs_file, test_data)
++    
++    # 创建副本
++    test_data["name"] = "Bob"
++    save(configs2_file, test_data)
++
++    settings = JSONConfig(
++        settings_files=[
++            configs_file,
++            configs2_file,
++        ]
++    )
++    # config2 优先级最高
++    assert settings.get("name")  == "Bob"
++
++    # 测试不存在的配置文件读取
++    settings = JSONConfig(
++        settings_files=[
++            configs_file,
++            "/tmp/not-exist.json",
++        ]
++    )
++    assert settings.get("name")  == "Alice"
++
++    # 不存在的配置项 读取时 走默认 
++    assert  settings.get("name1", "default") == "default"
++
++    # 测试不存在的配置文件读取
++    settings = JSONConfig(
++        settings_files=[
++            "/tmp/not-exist1.json",
++            "/tmp/not-exist.json",
++        ]
++    )
++    assert settings.get("name", "default") == "default"
++
++def test_parse_value():
++    save(configs_file, test_data)
++    
++    # 创建副本
++    test_data["local"]["pre"]["en"] = "xxxxx"
++    save(configs2_file, test_data)
++
++    settings = JSONConfig(
++        settings_files=[
++            configs_file,
++            configs2_file,
++        ]
++    )
++    assert settings.get("local",{}).get("pre",{}).get("en") == "xxxxx"
++    # 不存在的配置为默认
++    assert settings.get("loca1l",{}).get("pre",{}).get("zh","default") == "default"
++
++    #多级赋值
++    localsd = settings.get("local",{})
++    localsd["pre"]["en"] = "yyyyy"
++
++    assert settings.get("local",{}).get("pre",{}).get("en") == "yyyyy"
++
++    settings["me"] = "zzzzz"
++    # assert settings.me == "zzzzz"
++
++test_read_config()  # 通过
++
++test_parse_value()  # 通过
+\ No newline at end of file
+diff --git a/backend-immutable/tests/test-for-frontend.sh b/backend-immutable/tests/test-for-frontend.sh
+new file mode 100755
+index 0000000..41a46fd
+--- /dev/null
++++ b/backend-immutable/tests/test-for-frontend.sh
+@@ -0,0 +1,45 @@
++#!/bin/bash
++updater_program=$(pwd)/../kylin-system-updater
++
++. ./libtest.sh
++
++fn_simulate_ostree_system() {
++    # 模拟ostree系统的环境 进行测试
++    # 主要做的:
++    # - 初始化一个ostree仓库:testos-repo
++    # - 在osdata目录创建模拟一些系统文件 and 提交两次到testos-repo 仓库
++    # - 复制osdata数据到osdata-devel,做出修改然后再次提交
++    # - 用init-fs创建sysroot 和 os-init 和 syslinux
++    # - 提交一个新的commit用空目录,标记初始分支($BUILD_MASTER_BRACH)为EOL 重新定向到新分支(testos/buildmaster/newbranch)
++
++    # 创建ostree仓库 仓库类型 and boot类型 包括默认开启一个远程
++    setup_os_repository "archive" "syslinux"
++
++    rm $PUSH_FILE | true
++
++    cd ${test_tmpdir}
++    ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo remote add --set=gpg-verify=false testos $(cat httpd-address)/ostree/testos-repo
++
++    ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull testos $BUILD_MASTER_BRACH > /dev/null
++    rev=$(${CMD_PREFIX} ostree --repo=sysroot/ostree/repo rev-parse $BUILD_MASTER_BRACH)
++    echo "拉取分支:$BUILD_MASTER_BRACH 从远程仓库testos-repo and revision=${rev}"
++
++    echo "部署分支:$BUILD_MASTER_BRACH"
++    ${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os=testos testos:$BUILD_MASTER_BRACH > /dev/null
++    assert_has_dir sysroot/boot/ostree/testos-${bootcsum}
++}
++
++fn_simulate_ostree_system
++
++# 启动系统更新服务
++$updater_program -r -d --sysroot=$test_tmpdir/sysroot --os=testos &
++
++new_brach="testos/buildmaster/newbranch1"
++os_repository_new_commit 1 1 $new_brach
++
++echo -n "当前系统分支:$BUILD_MASTER_BRACH,配置切换到新分支$new_brach revision:"
++
++mkdir empty
++${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --tree=dir=$(pwd)/empty --add-metadata-string "ostree.endoflife-rebase=testos/buildmaster/newbranch1" -b testos/buildmaster/newbranch -s "EOL redirect to new branch"
++
++sleep 10000000
+\ No newline at end of file
+diff --git a/backend-immutable/tests/test-offline-upgrade.sh b/backend-immutable/tests/test-offline-upgrade.sh
+new file mode 100755
+index 0000000..722c153
+--- /dev/null
++++ b/backend-immutable/tests/test-offline-upgrade.sh
+@@ -0,0 +1,202 @@
++#!/bin/bash
++
++. ./libtest.sh
++
++test_delta_upgrade_progress() {
++    rm -rf  files repo temp-repo out.txt tmpsubdir repo2 deltadir repo3 deltadir | true
++    bindatafiles="bash true ostree"
++    morebindatafiles="false ls"
++
++    # 创建开始的仓库
++    mkdir repo
++    ostree_repo_init repo --mode=archive
++
++    # 创建一些测试文件
++    mkdir files
++    for bin in ${bindatafiles}; do
++        cp $(which ${bin}) files
++    done
++
++    # ----------------------------------------------服务端仓库 远程仓库-------------------------------------------
++    # 进行第一次提交 commit 到仓库
++    ${CMD_PREFIX} ostree --repo=repo commit -b test -s test --tree=dir=files
++    origrev=$(${CMD_PREFIX} ostree --repo=repo rev-parse test)
++
++    # 进行第二次提交 到仓库
++    cp /usr/bin/apt-get files
++    ${CMD_PREFIX} ostree --repo=repo commit -b test -s "原始版本" --tree=dir=files
++    newrev=$(${CMD_PREFIX} ostree --repo=repo rev-parse test)
++
++    # 第三次提交 到仓库    
++    cp /usr/bin/bash files
++    ${CMD_PREFIX} ostree --repo=repo commit --add-metadata-string=update-name="dsdsdd" -b test1 -s "最新更新"  --tree=dir=files
++    sedrev=$(${CMD_PREFIX} ostree --repo=repo rev-parse test1)
++
++    ${CMD_PREFIX} ostree --repo=repo static-delta generate --from=${origrev}  --to=${newrev} 
++    # 产生delta文件
++    ${CMD_PREFIX} ostree --repo=repo static-delta generate --from=${newrev}  --to=${sedrev} 
++
++    ${CMD_PREFIX} ostree --repo=repo summary -u
++
++    # ---------------------------------------------创建一个空仓库 + 离线数据-----------------------------------------
++    mkdir repo2 && ostree_repo_init repo2 --mode=archive
++
++    ${CMD_PREFIX} ostree --repo=repo2 remote add --set=gpg-verify=false repo file://$(pwd)/repo
++
++    # 拉取将要升级的源数据 
++    ${CMD_PREFIX} ostree --repo=repo2 pull --depth=-1 --commit-metadata-only repo test
++    ${CMD_PREFIX} ostree --repo=repo2 pull --depth=-1 --commit-metadata-only repo test1
++
++    # 放置delta差分数据
++    cp -r repo/deltas repo2/
++
++    # 复制服务都的summary文件 因为服务端包含完整的commit和分支数据 
++    cp -r repo/summary repo2/
++    # ${CMD_PREFIX} ostree --repo=repo2 summary -u
++
++    #-----------------------------------------------本地测试设备------------------------------------------------
++    # 创建空仓库
++    mkdir repo3 && ostree_repo_init repo3 --mode=bare
++
++    # 模拟 从服务端仓库拉取最开始的版本
++    ${CMD_PREFIX} ostree --repo=repo3 remote add --set=gpg-verify=false repo file://$(pwd)/repo
++    ${CMD_PREFIX} ostree --repo=repo3 pull repo test@${origrev}
++    ${CMD_PREFIX} ostree --repo=repo3 remote delete repo
++    rm -rf repo
++
++    # 配置本地仓库连接到 u盘源仓库
++    ${CMD_PREFIX} ostree --repo=repo3 remote add --set=gpg-verify=false repo file://$(pwd)/repo2
++
++    # 检查更新阶段
++    # ${CMD_PREFIX} ostree --repo=repo3 pull --depth=-1 --commit-metadata-only repo test
++    # ${CMD_PREFIX} ostree --repo=repo3 pull --depth=-1 --commit-metadata-only repo test1
++
++    # 下载阶段
++    ${CMD_PREFIX} ostree --repo=repo3 pull --require-static-deltas --depth=-1 repo test@${newrev}
++    ${CMD_PREFIX} ostree --repo=repo3 pull --require-static-deltas --depth=-1 repo test1@${sedrev}
++
++    echo "-------------"
++
++    ${CMD_PREFIX} ostree --repo=repo3 log repo:test
++    echo "-------------"
++}
++
++
++test_delta_upgrade() {
++    fn_simulate_ostree_system
++
++    OS_DATA="/tmp/ostree-auto-test/osdata"
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo static-delta generate --to=$BUILD_MASTER_BRACH
++    # 服务器 提交新的可升级补丁
++    cp /usr/bin/bash $OS_DATA
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit $metadata_string --add-metadata-string new_version=1.0.11 -b $BUILD_MASTER_BRACH -s "Build" --tree=dir=$OS_DATA
++    newrev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $BUILD_MASTER_BRACH)
++
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo static-delta generate --to=$BUILD_MASTER_BRACH
++
++    cp /usr/bin/apt-get $OS_DATA
++    echo "1" > $OS_DATA/usr/bin/content-iteration
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit $metadata_string --add-metadata-string new_version=1.0.11 -b $BUILD_MASTER_BRACH -s "Build" --tree=dir=$OS_DATA
++    sedrev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $BUILD_MASTER_BRACH)
++
++    # 产生delta文件
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo static-delta generate --to=$BUILD_MASTER_BRACH
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo summary -u
++
++    # ---------------------------------------------构建离线更新源-----------------------------------------
++    mkdir ${test_tmpdir}/offline-repo && ostree_repo_init ${test_tmpdir}/offline-repo --mode=archive
++
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/offline-repo remote add --set=gpg-verify=false testos file://${test_tmpdir}/testos-repo
++
++    # 拉取将要升级的源数据  需要拉取所有的元数据
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/offline-repo pull --depth=-1 --commit-metadata-only testos $BUILD_MASTER_BRACH
++
++    # 防止源数据
++    cp -r ${test_tmpdir}/testos-repo/deltas ${test_tmpdir}/offline-repo/
++
++    cp ${test_tmpdir}/testos-repo/summary ${test_tmpdir}/offline-repo/
++    # ----------------------------------------------------------------------------------------------------
++
++    ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo remote delete testos
++
++    ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo remote add --set=gpg-verify=false testos file://${test_tmpdir}/offline-repo
++
++    echo "testos:${BUILD_MASTER_BRACH}@${sedrev}" > $PUSH_FILE
++
++    echo ""
++    echo "检查更新"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$update_method > /dev/null
++    moniter_signal_success $update_finished_signal
++
++    echo "部署下载"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$download_method > /dev/null
++    moniter_signal_success $download_finished_signal
++
++    echo "部署内容"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$deploy_method > /dev/null
++    moniter_signal_success $deploy_finished_signal
++
++    # 部署完成后的检查
++    assert_file_has_content sysroot/boot/loader/entries/ostree-2-testos.conf "${bootcsum}"
++    rev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $BUILD_MASTER_BRACH)
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/usr/bin/content-iteration "1"
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0.origin "newbranch"
++}
++
++
++test_all_upgrade() {
++    fn_simulate_ostree_system
++
++    OS_DATA="/tmp/ostree-auto-test/osdata"
++
++    cp /usr/bin/bash $OS_DATA
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit $metadata_string --add-metadata-string new_version=1.0.11 -b $BUILD_MASTER_BRACH -s "Build" --tree=dir=$OS_DATA
++    newrev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $BUILD_MASTER_BRACH)
++
++    cp /usr/bin/apt-get $OS_DATA
++    echo "1" > $OS_DATA/usr/bin/content-iteration
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit $metadata_string --add-metadata-string new_version=1.0.11 -b $BUILD_MASTER_BRACH -s "Build" --tree=dir=$OS_DATA
++    sedrev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $BUILD_MASTER_BRACH)
++
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo summary -u
++
++    # ---------------------------------------------构建离线更新源-----------------------------------------
++    mkdir ${test_tmpdir}/offline-repo && ostree_repo_init ${test_tmpdir}/offline-repo --mode=archive
++
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/offline-repo remote add --set=gpg-verify=false testos file://${test_tmpdir}/testos-repo
++
++    # 拉取将要升级的源数据  需要拉取所有的元数据
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/offline-repo pull --depth=1 testos $BUILD_MASTER_BRACH@${sedrev}
++
++    # cp ${test_tmpdir}/testos-repo/summary ${test_tmpdir}/offline-repo/
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/offline-repo summary -u
++    # ----------------------------------------------------------------------------------------------------
++
++    ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo remote delete testos
++
++    ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo remote add --set=gpg-verify=false testos file://${test_tmpdir}/offline-repo
++
++    echo "testos:${BUILD_MASTER_BRACH}@${sedrev}" > $PUSH_FILE
++
++    echo ""
++    echo "检查更新"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$update_method > /dev/null
++    moniter_signal_success $update_finished_signal
++
++    echo "部署下载"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$download_method > /dev/null
++    moniter_signal_success $download_finished_signal
++
++    echo "部署内容"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$deploy_method > /dev/null
++    moniter_signal_success $deploy_finished_signal
++
++    # 部署完成后的检查
++    assert_file_has_content sysroot/boot/loader/entries/ostree-2-testos.conf "${bootcsum}"
++    rev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $BUILD_MASTER_BRACH)
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/usr/bin/content-iteration "1"
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0.origin "newbranch"
++}
++
++test_delta_upgrade
++test_all_upgrade
+\ No newline at end of file
+diff --git a/backend-immutable/tests/test-pull.sh b/backend-immutable/tests/test-pull.sh
+new file mode 100755
+index 0000000..0710028
+--- /dev/null
++++ b/backend-immutable/tests/test-pull.sh
+@@ -0,0 +1,39 @@
++#!/bin/bash
++
++. ./libtest.sh
++
++test_large_os_download() {
++    fn_simulate_ostree_system
++
++    info "测试下载超大文件 3.0G以上,花费时间较长 主要花费时间在commit内容上"
++
++    dd if=/dev/urandom of=${test_tmpdir}/osdata/random_data.bin bs=1G count=100
++    new_brach="testos/buildmaster/newbranch1"
++    os_repository_new_commit 1 1 $new_brach
++
++    mkdir empty
++    echo -n "当前系统分支:$BUILD_MASTER_BRACH,配置切换到新分支$new_brach revision:"
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --tree=dir=$(pwd)/empty --add-metadata-string "ostree.endoflife-rebase=testos/buildmaster/newbranch1" -b testos/buildmaster/newbranch -s "EOL redirect to new branch"
++
++    echo ""
++    echo "检查更新"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$update_method > /dev/null
++    moniter_signal_success $update_finished_signal
++
++    echo "部署下载"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$download_method > /dev/null
++    moniter_signal_success $download_finished_signal
++
++    echo "部署内容"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$deploy_method > /dev/null
++    moniter_signal_success $deploy_finished_signal
++
++    # 部署完成后的检查
++    assert_file_has_content sysroot/boot/loader/entries/ostree-2-testos.conf "${bootcsum}"
++    rev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $new_brach)
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/usr/bin/content-iteration "1"
++
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0.origin "newbranch"
++}
++
++test_large_os_download
+\ No newline at end of file
+diff --git a/backend-immutable/tests/test-push-update.sh b/backend-immutable/tests/test-push-update.sh
+new file mode 100755
+index 0000000..feabe2d
+--- /dev/null
++++ b/backend-immutable/tests/test-push-update.sh
+@@ -0,0 +1,201 @@
++#!/bin/bash
++
++. ./libtest.sh
++
++test_only_branch() {
++    fn_simulate_ostree_system
++
++    new_brach="testos/buildmaster/newbranch1"
++    os_repository_new_commit 1 1 $new_brach
++    push_content="testos:${new_brach}"
++
++    info "测试:推送更新内容,仅包含分支信息,推送内容:$push_content"
++
++    echo "${push_content}" > $PUSH_FILE
++
++    echo "检查更新"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$update_method > /dev/null
++    moniter_signal_success $update_finished_signal
++
++    echo "部署下载"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$download_method > /dev/null
++    moniter_signal_success $download_finished_signal
++    
++
++    echo "部署内容"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$deploy_method > /dev/null
++    moniter_signal_success $deploy_finished_signal
++
++    # 部署完成后的检查
++    assert_file_has_content sysroot/boot/loader/entries/ostree-2-testos.conf "${bootcsum}"
++    rev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $new_brach)
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/usr/bin/content-iteration "1"
++
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0.origin "newbranch"
++}
++
++test_new_branch_and_commit() {
++    fn_simulate_ostree_system
++    new_brach="testos/buildmaster/newbranch1"
++    os_repository_new_commit 1 1 $new_brach
++    newrev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $new_brach)
++
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit $metadata_string --add-metadata-string new_version=1.0.11 -b $BUILD_MASTER_BRACH -s "Build" --tree=dir=$OS_DATA
++
++    push_content="testos:${new_brach}@$newrev"
++
++    info "测试:推送更新内容:$push_content"
++
++    echo "$push_content" > $PUSH_FILE
++
++    echo "检查更新"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$update_method > /dev/null
++    moniter_signal_success $update_finished_signal
++
++    echo "部署下载"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$download_method > /dev/null
++    moniter_signal_success $download_finished_signal
++
++    echo "部署内容"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$deploy_method > /dev/null
++    moniter_signal_success $deploy_finished_signal
++
++    # 部署完成后的检查
++    assert_file_has_content sysroot/boot/loader/entries/ostree-2-testos.conf "${bootcsum}"
++    # rev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $new_brach)
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/usr/bin/content-iteration "1"
++
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0.origin "newbranch"
++}
++
++test_new_branch_and_old_commit() {
++    echo "测试部署新分支 并且提交的commit在"
++    fn_simulate_ostree_system
++    new_brach="testos/buildmaster/newbranch1"
++
++    # 再次提交保持不是最新的
++    os_repository_new_commit 1 1 $new_brach
++    newrev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $new_brach)
++
++    os_repository_new_commit 1 1 $new_brach
++    push_content="testos:${new_brach}@$newrev"
++
++    info "测试:推送更新内容:$push_content"
++
++    echo "$push_content" > $PUSH_FILE
++
++
++    echo "检查更新"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$update_method > /dev/null
++    moniter_signal_success $update_finished_signal
++
++    
++    echo "部署下载"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$download_method > /dev/null
++    moniter_signal_success $download_finished_signal
++
++    echo "部署内容"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$deploy_method > /dev/null
++    moniter_signal_success $deploy_finished_signal
++
++    # 部署完成后的检查
++    assert_file_has_content sysroot/boot/loader/entries/ostree-2-testos.conf "${bootcsum}"
++    # rev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $new_brach)
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/usr/bin/content-iteration "1"
++
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0.origin "newbranch"
++}
++
++
++
++test_old_branch_and_commit() {
++    fn_simulate_ostree_system
++
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit $metadata_string --add-metadata-string new_version=1.0.11 -b $BUILD_MASTER_BRACH -s "Build" --tree=dir=$OS_DATA
++    newrev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $BUILD_MASTER_BRACH)
++
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit $metadata_string --add-metadata-string new_version=1.0.12 -b $BUILD_MASTER_BRACH -s "Build" --tree=dir=$OS_DATA
++
++    push_content="testos:${BUILD_MASTER_BRACH}@$newrev"
++    info "测试分支@commit号,例如推送更新内容:$push_content"
++
++    echo $push_content > $PUSH_FILE
++
++    echo "检查更新"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$update_method > /dev/null
++    moniter_signal_success $update_finished_signal
++
++    echo "部署下载"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$download_method > /dev/null
++    moniter_signal_success $download_finished_signal
++
++    echo "部署内容"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$deploy_method > /dev/null
++    moniter_signal_success $deploy_finished_signal
++
++    # 部署完成后的检查
++    # rev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $new_brach)
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/usr/bin/sh "executable"
++    assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0.origin "newbranch"
++}
++test_on_push_update() {
++    info "测试 没有推送更新文件的情况并且不切换分支,直接提示最新的。"
++    if [ -f "$PUSH_FILE" ]; then
++        rm $PUSH_FILE | true
++    fi
++
++    fn_simulate_ostree_system
++
++    ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit $metadata_string --add-metadata-string new_version=1.0.11 -b $BUILD_MASTER_BRACH -s "Build" --tree=dir=$OS_DATA
++    newrev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $BUILD_MASTER_BRACH)
++
++    echo ""
++    echo "测试:推送更新内容,升级到当前分支 $BUILD_MASTER_BRACH @$newrev"
++
++    echo ""
++    echo "检查更新"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$update_method > /dev/null
++
++    moniter_string "$update_finished_signal success = True , upgrade_group = \[\]"
++}
++test_exeption_push() {
++    fn_simulate_ostree_system
++
++    new_brach="testos/buildmaster/newbranch1"
++    os_repository_new_commit 1 1 $new_brach
++    push_content="${new_brach}"
++
++    info "测试:推送更新内容异常情况,推送内容:$push_content"
++
++    echo "${push_content}" > $PUSH_FILE
++
++    echo "检查更新"
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$update_method > /dev/null
++
++    # 提示为最新
++    moniter_string "$update_finished_signal success = True , upgrade_group = \[\]"
++
++    info "测试:推送错误的分支。"
++    push_content="testos:dddd"
++    echo "${push_content}" > $PUSH_FILE
++    gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$update_method > /dev/null
++    moniter_string "$update_finished_signal success = False , upgrade_group = \[''\], error_code = #0003"
++
++    # info "测试:推送错误的commit号。"
++    # push_content="testos:${new_brach}@dsdsdsdsdsds"
++    # echo "${push_content}" > $PUSH_FILE
++    # gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$update_method > /dev/null
++    # moniter_string "$update_finished_signal success = False , upgrade_group = \[''\]"
++}
++
++test_on_push_update
++
++test_only_branch
++
++test_new_branch_and_commit
++
++test_old_branch_and_commit
++
++test_exeption_push
++
++test_new_branch_and_old_commit
+\ No newline at end of file
+diff --git a/backend-immutable/tests/test-upgrade-endoflife.sh b/backend-immutable/tests/test-upgrade-endoflife.sh
+new file mode 100755
+index 0000000..732b514
+--- /dev/null
++++ b/backend-immutable/tests/test-upgrade-endoflife.sh
+@@ -0,0 +1,54 @@
++#!/bin/bash
++
++. ./libtest.sh
++
++test_deploy_limit() {
++    
++    fn_simulate_ostree_system
++    if [ -f "$PUSH_FILE" ]; then
++        rm $PUSH_FILE | true
++    fi
++
++    for ((i=1; i<=$1; i++))
++    do
++        y=$((i - 1))
++
++        if [ $y -eq 0 ]; then
++            y=""
++        fi
++        echo ""
++        echo "测试:从当前分支切换到新分支部署升级"
++
++        new_brach="testos/buildmaster/newbranch$i"
++        os_repository_new_commit 1 1 $new_brach
++
++        mkdir empty$i
++        echo -n "当前系统分支:$BUILD_MASTER_BRACH,配置切换到新分支$new_brach revision:"
++        ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --tree=dir=$(pwd)/empty$i --add-metadata-string "ostree.endoflife-rebase=testos/buildmaster/newbranch$i" -b testos/buildmaster/newbranch$y -s "EOL redirect to new branch"
++
++        echo ""
++        echo "Ostree 测试环境创建成功, 开始系统更新功能测试"
++        echo ""
++
++        echo "检查更新"
++        gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$update_method > /dev/null
++        moniter_signal_success $update_finished_signal
++
++        echo "部署下载"
++        gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$download_method > /dev/null
++        moniter_signal_success $download_finished_signal
++
++        echo "部署内容"
++        gdbus call --system --dest $bus_name --object-path $object_path --method $interface_name.$deploy_method > /dev/null
++        moniter_signal_success $deploy_finished_signal
++
++        # 部署完成后的检查
++        assert_file_has_content sysroot/boot/loader/entries/ostree-2-testos.conf "${bootcsum}"
++        rev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo rev-parse $new_brach)
++        assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/usr/bin/content-iteration "1"
++
++        assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0.origin "newbranch"
++    done
++}
++
++test_deploy_limit 1
diff -Nru kylin-system-updater-3.0.0.0/debian/patches/series kylin-system-updater-3.0.0.0/debian/patches/series
--- kylin-system-updater-3.0.0.0/debian/patches/series	2024-11-27 13:56:00.000000000 +0800
+++ kylin-system-updater-3.0.0.0/debian/patches/series	2025-02-25 14:13:19.000000000 +0800
@@ -23,3 +23,4 @@
 0023-changelog-3.0.0.0-ok29.patch
 0024-2.patch
 0025-3.0.0.0-ok32.patch
+0026-changelog-3.0.0.0-ok33.patch