Merge branch 'uu_test' into 'backend_uu'
add os-release info See merge request kylin-desktop/update-manager-group/kylin-system-updater!398
This commit is contained in:
commit
f7e45dd10d
|
@ -17,13 +17,10 @@ backend/data/unattended-upgrades-policy.conf /var/lib/unattended-upgrades/
|
|||
|
||||
#uu
|
||||
unattended-upgrades/*.service /lib/systemd/system/
|
||||
unattended-upgrades/*.timer /lib/systemd/system/
|
||||
unattended-upgrades/unattended-upgrades-daily /usr/bin/
|
||||
unattended-upgrades/notify /usr/bin/
|
||||
unattended-upgrades/*.desktop /etc/xdg/autostart/
|
||||
unattended-upgrades/kylin-unattended-upgrade /usr/bin
|
||||
unattended-upgrades/kylin-unattended-upgrade-shutdown /usr/bin
|
||||
unattended-upgrades/unattended-upgrades-daily /usr/bin
|
||||
unattended-upgrades/kylin-unattended-upgrades /etc/apt/apt.conf.d/
|
||||
unattended-upgrades/logrotate.d/* /etc/logrotate.d/
|
||||
unattended-upgrades/kylin-unattended-upgrades-logind-maxdelay.conf /usr/lib/systemd/logind.conf.d/
|
||||
|
|
|
@ -9,11 +9,8 @@ fi
|
|||
systemctl enable kylin-system-updater.service
|
||||
|
||||
mkdir -p /var/lib/unattended-upgrades
|
||||
chmod +x /usr/bin/unattended-upgrades-daily
|
||||
chmod +x /usr/bin/kylin-unattended-upgrade
|
||||
chmod +x /usr/bin/kylin-unattended-upgrade-shutdown
|
||||
systemctl enable unattended-upgrades-download.timer
|
||||
systemctl enable unattended-upgrades-install.timer
|
||||
systemctl enable kylin-unattended-upgrades.service
|
||||
if [ -f /usr/share/kylin-system-updater/SystemUpdater/Core/DataMigration.py ];then
|
||||
echo "Database record migration"
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
# along with unattended-upgrades; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
import stat
|
||||
import atexit
|
||||
import copy
|
||||
import datetime
|
||||
|
@ -92,6 +92,7 @@ import fcntl
|
|||
import time
|
||||
import subprocess
|
||||
|
||||
OTA_RESULT_FILE_PATH="/opt/apt_result/ota_result"
|
||||
SYSTEM_UPDATER_CORE_LIB_PATH="/usr/share/kylin-system-updater/SystemUpdater/Core"
|
||||
sys.path.append(SYSTEM_UPDATER_CORE_LIB_PATH)
|
||||
from OriginFilter import UnattendUpgradeFilter
|
||||
|
@ -129,6 +130,20 @@ SHUTDOWN_BLOCK_FILELOCK = "kylin-update.lock"
|
|||
pidfile = None
|
||||
# set from the sigint signal handler
|
||||
SIGNAL_STOP_REQUEST = False
|
||||
|
||||
def ReadOsRelease(file):
|
||||
osreleasedict={}
|
||||
try:
|
||||
with open(file) as f:
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
ls = line.strip().split('=',1)
|
||||
osreleasedict.update({ls[0]:ls[1]})
|
||||
except Exception as e:
|
||||
pass
|
||||
return osreleasedict
|
||||
|
||||
|
||||
#安装时禁止关机 进行加锁
|
||||
def LockedPreventShutdown():
|
||||
global pidfile
|
||||
|
@ -365,6 +380,12 @@ class KylinSystemUpdater:
|
|||
self.update_interface = dbus.Interface(self.update_proxy,dbus_interface='com.kylin.systemupgrade.interface')
|
||||
self.success = False
|
||||
|
||||
def GetConfigValue(self,section,value):
|
||||
return self.update_interface.GetConfigValue(section,value)
|
||||
|
||||
def SetConfigValue(self,section,option,value):
|
||||
return self.update_interface.SetConfigValue(section,option,value)
|
||||
|
||||
def GetWhiteList(self):
|
||||
ret = self.update_interface.UpdateDetect()
|
||||
return ret
|
||||
|
@ -466,6 +487,52 @@ class KylinBackupManager:
|
|||
logging.info("backup manager:quiting mainloop")
|
||||
self.loop.quit()
|
||||
|
||||
def ReadValueFromFile(file,section,option):
|
||||
config=configparser.ConfigParser(allow_no_value=True)
|
||||
try:
|
||||
config.read(file)
|
||||
value = config[section][option]
|
||||
except Exception as e:
|
||||
return None
|
||||
return value
|
||||
|
||||
def Backup():
|
||||
# do backup
|
||||
kylin_backup_manager = KylinBackupManager()
|
||||
backup_partition_status = kylin_backup_manager.mount_backup_partition()
|
||||
if backup_partition_status not in [0,5]:
|
||||
logging.error("backup partition error:%d"%backup_partition_status)
|
||||
return UnattendedUpgradesResult(False,"backup partition error")
|
||||
status_code,result = kylin_backup_manager.get_backup_state()
|
||||
if result == 0 and status_code == 99:
|
||||
pass
|
||||
else:
|
||||
logging.error("backup state error:",status_code,result)
|
||||
return UnattendedUpgradesResult(False,"backup state error")
|
||||
#node_name,node_status = kylin_backup_manager.get_backup_comment_for_systemupdate()
|
||||
ts = get_timestamp()
|
||||
kylin_backup_manager.ConnectToSignals()
|
||||
create_note = "系统升级新建备份"
|
||||
inc_note="系统升级增量备份"
|
||||
userName="root"
|
||||
uid=os.getuid()
|
||||
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","backup")
|
||||
kylin_backup_manager.auto_backup_for_system_update_noreturn(ts,create_note,inc_note,userName,uid)
|
||||
kylin_backup_manager.RunMainloop()
|
||||
'''
|
||||
if node_name != timeStamp:
|
||||
logging.info("need backup")
|
||||
#do actual backup
|
||||
kylin_backup_manager.ConnectToSignals()
|
||||
create_note = "系统升级新建备份"
|
||||
inc_note="系统升级增量备份"
|
||||
userName="root"
|
||||
uid=os.getuid()
|
||||
kylin_backup_manager.auto_backup_for_system_update_noreturn(timeStamp,create_note,inc_note,userName,uid)
|
||||
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","backup")
|
||||
kylin_backup_manager.RunMainloop()
|
||||
'''
|
||||
|
||||
PkgPin = namedtuple('PkgPin', ['pkg', 'priority'])
|
||||
PkgFilePin = namedtuple('PkgFilePin', ['id', 'priority'])
|
||||
|
||||
|
@ -683,7 +750,7 @@ class UnattendedUpgradesCache(apt.Cache):
|
|||
# Only adjust to lower versions to avoid flipping back and forth
|
||||
# and to avoid picking a newer version, not selected by apt.
|
||||
# This helps avoiding upgrades to experimental's packages.
|
||||
if pkg.candidate is not None and new_cand < pkg.candidate:
|
||||
if pkg.candidate is not None: #and new_cand < pkg.candidate:
|
||||
logging.debug("adjusting candidate version: %s" % new_cand)
|
||||
pkg.candidate = new_cand
|
||||
return True
|
||||
|
@ -1025,6 +1092,7 @@ def should_stop():
|
|||
if SIGNAL_STOP_REQUEST:
|
||||
logging.warning("SIGNAL received, stopping")
|
||||
return True
|
||||
'''
|
||||
try:
|
||||
if apt_pkg.config.find_b("Unattended-Upgrade::OnlyOnACPower", True) \
|
||||
and subprocess.call("on_ac_power") == 1:
|
||||
|
@ -1046,6 +1114,7 @@ def should_stop():
|
|||
log_once(_("Checking if connection is metered is skipped. Please "
|
||||
"install python3-gi package to detect metered "
|
||||
"connections and skip downloading updates."))
|
||||
'''
|
||||
return False
|
||||
|
||||
|
||||
|
@ -1272,7 +1341,11 @@ def upgrade_in_minimal_steps(cache, # type: UnattendedUpgradesCache
|
|||
continue
|
||||
if should_stop():
|
||||
return False
|
||||
pkg = cache[pkgname]
|
||||
try:
|
||||
pkg = cache[pkgname]
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
try:
|
||||
if pkg.is_upgradable \
|
||||
or candidate_version_changed(pkg):
|
||||
|
@ -1446,7 +1519,10 @@ def upgrade_order(to_upgrade, cache):
|
|||
# calculate upgrade sets
|
||||
follow_deps = {'Depends', 'PreDepends', 'Recommends'}
|
||||
for pkgname in to_upgrade:
|
||||
pkg = cache[pkgname]
|
||||
try:
|
||||
pkg = cache[pkgname]
|
||||
except KeyError:
|
||||
continue
|
||||
upgrade_set_sizes[pkgname] = len(transitive_dependencies(
|
||||
pkg, cache, valid_types=follow_deps).intersection(to_upgrade))
|
||||
return sorted(upgrade_set_sizes, key=upgrade_set_sizes.get)
|
||||
|
@ -2262,7 +2338,11 @@ def do_auto_remove(cache, # type: UnattendedUpgradesCache
|
|||
logging.debug("marking %s for removal" % pkgname)
|
||||
if pkgname in pkgs_removed:
|
||||
continue
|
||||
cache[pkgname].mark_delete()
|
||||
try:
|
||||
pkg = cache[pkgname]
|
||||
except KeyError:
|
||||
continue
|
||||
pkg.mark_delete()
|
||||
if not is_autoremove_valid(cache, pkgname, auto_removable):
|
||||
# this situation can occur when removing newly unused packages
|
||||
# would also remove old unused packages which are not set
|
||||
|
@ -2281,7 +2361,11 @@ def do_auto_remove(cache, # type: UnattendedUpgradesCache
|
|||
cache.clear()
|
||||
else:
|
||||
for pkgname in auto_removable:
|
||||
cache[pkgname].mark_delete()
|
||||
try:
|
||||
pkg = cache[pkgname]
|
||||
except KeyError:
|
||||
continue
|
||||
pkg.mark_delete()
|
||||
if is_autoremove_valid(cache, "", auto_removable):
|
||||
# do it in one step
|
||||
if not dry_run:
|
||||
|
@ -2375,7 +2459,8 @@ def main(options, rootdir="/"):
|
|||
if not os.path.exists(logfile_dpkg):
|
||||
with open(logfile_dpkg, 'w'):
|
||||
pass
|
||||
|
||||
global os_release_info
|
||||
os_release_info = ReadOsRelease('/etc/os-release')
|
||||
# lock for the shutdown check
|
||||
# shutdown_lock = apt_pkg.get_lock(LOCK_FILE)
|
||||
# if shutdown_lock < 0:
|
||||
|
@ -2386,6 +2471,22 @@ def main(options, rootdir="/"):
|
|||
try:
|
||||
res = run(options, rootdir, mem_log, logfile_dpkg,
|
||||
install_start_time)
|
||||
localtime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))
|
||||
config_to_result = configparser.ConfigParser(allow_no_value=True)
|
||||
config_to_result.add_section("OTA")
|
||||
config_to_result.set("OTA","time",localtime)
|
||||
config_to_result.set("OTA","version","1.0")
|
||||
config_to_result.set("OTA","upgrade","0")
|
||||
config_to_result.set("OTA","status","failed")
|
||||
if res.success and options.mode == 'shutdown':
|
||||
if len(res.pkgs) > 0 :
|
||||
config_to_result.set("OTA","upgrade","1")
|
||||
config_to_result.set("OTA","status","success")
|
||||
|
||||
config_to_result.set("OTA","status","success")
|
||||
with open(OTA_RESULT_FILE_PATH,"w+") as f:
|
||||
config_to_result.write(f)
|
||||
os.chmod(OTA_RESULT_FILE_PATH,stat.S_IRWXU|stat.S_IRWXG|stat.S_IRWXO)
|
||||
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle")
|
||||
if res.success and res.result_str:
|
||||
# complete, successful run
|
||||
|
@ -2431,7 +2532,10 @@ def main(options, rootdir="/"):
|
|||
def mark_pkgs_to_upgrade(cache, pkgs_to_upgrade):
|
||||
# type (apt.Cache, List[str]) -> None
|
||||
for pkg_name in pkgs_to_upgrade:
|
||||
pkg = cache[pkg_name]
|
||||
try:
|
||||
pkg = cache[pkg_name]
|
||||
except KeyError:
|
||||
continue
|
||||
if pkg.is_upgradable \
|
||||
or (pkg.is_installed
|
||||
and pkg.candidate.version != pkg.installed.version) \
|
||||
|
@ -2444,7 +2548,10 @@ def mark_pkgs_to_upgrade(cache, pkgs_to_upgrade):
|
|||
|
||||
def adjust_candidate_with_version(cache,pkgnamelist,versionlist):
|
||||
for pkgname in pkgnamelist:
|
||||
pkg = cache[pkgname]
|
||||
try:
|
||||
pkg = cache[pkgname]
|
||||
except KeyError:
|
||||
continue
|
||||
for v in pkg.versions:
|
||||
if is_in_allowed_origin(v,cache.allowed_origins):
|
||||
if str(v) in versionlist:
|
||||
|
@ -2459,13 +2566,13 @@ def run(options, # type: Options
|
|||
# type: (...) -> UnattendedUpgradesResult
|
||||
|
||||
# check if today is a patch day
|
||||
if not is_update_day():
|
||||
return UnattendedUpgradesResult(True)
|
||||
# if not is_update_day():
|
||||
# return UnattendedUpgradesResult(True)
|
||||
|
||||
# check if u-u should be stopped already
|
||||
if should_stop():
|
||||
return UnattendedUpgradesResult(False)
|
||||
|
||||
global os_release_info
|
||||
# check to see if want to auto-upgrade the devel release
|
||||
'''
|
||||
if apt_pkg.config.find("Unattended-Upgrade::DevRelease") == "auto":
|
||||
|
@ -2524,6 +2631,7 @@ def run(options, # type: Options
|
|||
# check if the journal is dirty and if so, take emergceny action
|
||||
# the alternative is to leave the system potentially unsecure until
|
||||
# the user comes in and fixes
|
||||
'''
|
||||
if is_dpkg_journal_dirty() and \
|
||||
apt_pkg.config.find_b("Unattended-Upgrade::AutoFixInterruptedDpkg",
|
||||
False):
|
||||
|
@ -2541,7 +2649,7 @@ def run(options, # type: Options
|
|||
except subprocess.CalledProcessError as e:
|
||||
output = e.output
|
||||
logging.warning(_("dpkg --configure -a output:\n%s"), output)
|
||||
|
||||
'''
|
||||
config_manager = ConfigFileManager(CONFIG_FILE_ROOT_PATH)
|
||||
white_list = config_manager.ReadListFromFile(WHITE_LIST_FILE_PATH,'AutoUpgrade','upgradelist')
|
||||
global wl
|
||||
|
@ -2633,12 +2741,19 @@ def run(options, # type: Options
|
|||
#only write the pkg list when dpkg journal is clean
|
||||
if not is_dpkg_journal_dirty():
|
||||
configfilemanager.WriteListToFile(pkgs,"OTA_PKGS_TO_INSTALL_LIST")
|
||||
|
||||
try:
|
||||
res = fetcher.run()
|
||||
logging.debug("fetch.run() result: %s", res)
|
||||
except SystemError as e:
|
||||
logging.error("fetch.run() result: %s", e)
|
||||
logging.error("fetch.run() result: %s", e)
|
||||
|
||||
if options.mode == 'shutdown':
|
||||
if kylin_system_updater.GetConfigValue('InstallMode','shutdown_install'):
|
||||
pass
|
||||
else:
|
||||
logging.info("system updater need to run shutdown install quiting...")
|
||||
return UnattendedUpgradesResult(False,_("system updater install override"))
|
||||
|
||||
|
||||
elif options.download_only:
|
||||
if fetcher_statistics.remote_pkg_amount>0:
|
||||
|
@ -2666,9 +2781,24 @@ def run(options, # type: Options
|
|||
except SystemError as e:
|
||||
logging.error(_("GetArchives() failed: %s"), e)
|
||||
else:
|
||||
logging.info("all pkgs downloaded")
|
||||
configfilemanager.AddFileName("OTA_PKGS_TO_INSTALL")
|
||||
return UnattendedUpgradesResult(True,_("all pkgs downloaded"))
|
||||
docker_image_fetch_result = 0
|
||||
#docker image fetch for mavis and laika
|
||||
if os.path.exists("/usr/bin/service_runtime_ota.sh"):
|
||||
docker_image_fetch_result = subprocess.run(["/usr/bin/service_runtime_ota.sh"], shell=True)
|
||||
if docker_image_fetch_result == 0:
|
||||
logging.info("all pkgs downloaded")
|
||||
insmod = ReadValueFromFile("/var/lib/unattended-upgrades/unattended-upgrades-policy.conf","autoUpgradePolicy","installMode")
|
||||
if insmod == 'bshutdown':
|
||||
configfilemanager.AddFileName("OTA_PKGS_TO_INSTALL")
|
||||
subprocess.Popen('dbus-send --system --type=signal / com.kylin.update.notification.DownloadFinish', shell=True)
|
||||
kylin_system_updater.SetConfigValue('InstallMode','auto_install','True')
|
||||
elif insmod == 'timing':
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
return UnattendedUpgradesResult(True,_("all pkgs downloaded"))
|
||||
else:
|
||||
return UnattendedUpgradesResult(False,_("docker fetch failed"))
|
||||
return UnattendedUpgradesResult(False,_("some pkgs incompletely fetched"))
|
||||
else:
|
||||
logging.debug(_("option is not install-only or download-only"))
|
||||
|
@ -2842,41 +2972,13 @@ def run(options, # type: Options
|
|||
# only perform install step if we actually have packages to install
|
||||
pkg_install_success = True
|
||||
if len(pkgs_to_upgrade) > 0:
|
||||
# do backup
|
||||
kylin_backup_manager = KylinBackupManager()
|
||||
backup_partition_status = kylin_backup_manager.mount_backup_partition()
|
||||
if backup_partition_status not in [0,5]:
|
||||
logging.error("backup partition error:%d"%backup_partition_status)
|
||||
return UnattendedUpgradesResult(False,"backup partition error")
|
||||
status_code,result = kylin_backup_manager.get_backup_state()
|
||||
if result == 0 and status_code == 99:
|
||||
pass
|
||||
else:
|
||||
logging.error("backup state error:",status_code,result)
|
||||
return UnattendedUpgradesResult(False,"backup state error")
|
||||
#node_name,node_status = kylin_backup_manager.get_backup_comment_for_systemupdate()
|
||||
ts = get_timestamp()
|
||||
kylin_backup_manager.ConnectToSignals()
|
||||
create_note = "系统升级新建备份"
|
||||
inc_note="系统升级增量备份"
|
||||
userName="root"
|
||||
uid=os.getuid()
|
||||
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","backup")
|
||||
kylin_backup_manager.auto_backup_for_system_update_noreturn(ts,create_note,inc_note,userName,uid)
|
||||
kylin_backup_manager.RunMainloop()
|
||||
'''
|
||||
if node_name != timeStamp:
|
||||
logging.info("need backup")
|
||||
#do actual backup
|
||||
kylin_backup_manager.ConnectToSignals()
|
||||
create_note = "系统升级新建备份"
|
||||
inc_note="系统升级增量备份"
|
||||
userName="root"
|
||||
uid=os.getuid()
|
||||
kylin_backup_manager.auto_backup_for_system_update_noreturn(timeStamp,create_note,inc_note,userName,uid)
|
||||
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","backup")
|
||||
kylin_backup_manager.RunMainloop()
|
||||
'''
|
||||
if 'PROJECT_CODENAME' in os_release_info:
|
||||
if os_release_info['PROJECT_CODENAME']=='V10SP1-edu':
|
||||
if 'SUB_PROJECT_CODENAME' in os_release_info:
|
||||
if os_release_info['SUB_PROJECT_CODENAME']=='mavis':
|
||||
pass
|
||||
else:
|
||||
Backup()
|
||||
# do install
|
||||
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","install")
|
||||
#send install start msg to notify
|
||||
|
@ -2978,6 +3080,7 @@ class Options:
|
|||
self.apt_debug = False
|
||||
self.verbose = False
|
||||
self.minimal_upgrade_steps = False
|
||||
self.mode = None
|
||||
|
||||
shutdown_lock = -1
|
||||
|
||||
|
@ -2985,7 +3088,7 @@ if __name__ == "__main__":
|
|||
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle")
|
||||
# lock for the shutdown check
|
||||
shutdown_lock = apt_pkg.get_lock(LOCK_FILE)
|
||||
if shutdown_lock < 0:
|
||||
if shutdown_lock < 0:
|
||||
logging.error("Lock file is already taken, exiting")
|
||||
#WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle")
|
||||
sys.exit(0)
|
||||
|
@ -3042,6 +3145,7 @@ if __name__ == "__main__":
|
|||
action="store_true",
|
||||
help=SUPPRESS_HELP,
|
||||
default=minimal_steps_default)
|
||||
parser.add_option(""''"","--mode",action = "store",type = "string" ,dest = "mode",help="start mode.")
|
||||
options = cast(Options, (parser.parse_args())[0])
|
||||
|
||||
if os.getuid() != 0:
|
||||
|
@ -3067,7 +3171,6 @@ if __name__ == "__main__":
|
|||
atexit.register(os.remove, pidf)
|
||||
system_updater = KylinSystemUpdater()
|
||||
allow_autoupdate = system_updater.GetDatabaseInfo("display","autoupdate_allow")
|
||||
|
||||
if allow_autoupdate == "true":
|
||||
pass
|
||||
else:
|
||||
|
|
|
@ -30,6 +30,7 @@ import dbus
|
|||
import signal
|
||||
import sys
|
||||
import time
|
||||
import datetime
|
||||
import logging
|
||||
import logging.handlers
|
||||
import gettext
|
||||
|
@ -48,6 +49,10 @@ from optparse import OptionParser, Values
|
|||
Values # pyflakes
|
||||
from gettext import gettext as _
|
||||
from threading import Event
|
||||
from enum import IntEnum, Enum
|
||||
from apscheduler.schedulers.blocking import BlockingScheduler
|
||||
import random
|
||||
import threading
|
||||
|
||||
try:
|
||||
import apt_pkg
|
||||
|
@ -56,11 +61,68 @@ except Exception:
|
|||
# need to stop the shutdown
|
||||
logging.exception("importing of apt_pkg failed, exiting")
|
||||
sys.exit(0)
|
||||
|
||||
## analytic unattended-upgrades-policy.conf start
|
||||
POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY = "autoUpgradePolicy"
|
||||
AUTO_UPGRADE_POLICY_OPTION_PREDOWNLOAD = "preDownload"
|
||||
AUTO_UPGRADE_POLICY_OPTION_AUTOUPGRADE = "autoUpgradeState"
|
||||
AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_MODE = "downloadMode"
|
||||
AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_TIME = "downloadTime"
|
||||
AUTO_UPGRADE_POLICY_OPTION_INSTALL_MODE = "installMode"
|
||||
INTERVAL_DOWN_INSTALL = 120 # 下载安装的间隔 分钟
|
||||
INSTALL_RANDOM = 5 # 安装时间随机数范围0-INSTALL_RANDOM 分钟
|
||||
DOWNLOAD_RANDOM = 3 # 下载时间随机数范围0-DOWNLOAD_RANDOM 分钟
|
||||
|
||||
class FeatureSwitch(Enum):
|
||||
ON = 'on'
|
||||
OFF = 'off'
|
||||
|
||||
class DownloadMode(Enum): # 下载模式
|
||||
TIMING_DOWNLOAD = 'timing' # 定时下载
|
||||
MANUAL_DOWNLOAD = 'manual' # 手动下载
|
||||
|
||||
class InstallMode(Enum): # 安装模式
|
||||
TIMING_INSTALL = 'timing' # 定时安装
|
||||
MANUAL_INSTALL = 'manual' # 手动安装
|
||||
BEFORE_SHUTDOWN_INSTALL = 'bshutdown' # 关机前安装
|
||||
|
||||
class TimeElement(IntEnum):
|
||||
TIME_HOUR = 0
|
||||
TIME_MINUTE = 1
|
||||
TIME_NUM = 2
|
||||
|
||||
## analytic unattended-upgrades-policy.conf end
|
||||
|
||||
UNATTENDED_UPGRADE_CONFIG_FILE_PATH="/var/lib/unattended-upgrades/unattended-upgrade.conf"
|
||||
UNATTENDED_UPGRADE_POLICY_FILE_PATH="/var/lib/unattended-upgrades/unattended-upgrades-policy.conf"
|
||||
NOTIFICATION_PIPE = '/tmp/notification.pipe'
|
||||
|
||||
flag_file_list = ["/var/lib/unattended-upgrades/OTA_PKGS_TO_INSTALL",\
|
||||
"/var/lib/kylin-auto-upgrade/kylin-autoupgrade.conf","/tmp/notify.pid"]
|
||||
|
||||
def GetDateTime():
|
||||
return datetime.datetime.now().replace(microsecond=0)
|
||||
|
||||
def ReadOsRelease(file):
|
||||
osreleasedict = {}
|
||||
try:
|
||||
with open(file) as f:
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
ls = line.strip().split('=',1)
|
||||
osreleasedict.update({ls[0]:ls[1]})
|
||||
except Exception as e:
|
||||
pass
|
||||
return osreleasedict
|
||||
|
||||
def ReadValueFromFile(file,section,option):
|
||||
config=configparser.ConfigParser(allow_no_value=True)
|
||||
try:
|
||||
config.read(file)
|
||||
value = config[section][option]
|
||||
except Exception as e:
|
||||
return None
|
||||
return value
|
||||
|
||||
def WriteValueToFile(file,section,option,value):
|
||||
config=configparser.ConfigParser(allow_no_value=True)
|
||||
|
@ -76,14 +138,14 @@ def clean_flag_files(filelist):
|
|||
def init():
|
||||
if not os.path.exists(NOTIFICATION_PIPE):
|
||||
os.mkfifo(NOTIFICATION_PIPE)
|
||||
|
||||
'''
|
||||
def do_usplash(msg):
|
||||
# type: (str) -> None
|
||||
if os.path.exists("/sbin/usplash_write"):
|
||||
logging.debug("Running usplash_write")
|
||||
subprocess.call(["/sbin/usplash_write", "TEXT", msg])
|
||||
subprocess.call(["/sbin/usplash_write", "PULSATE"])
|
||||
|
||||
'''
|
||||
|
||||
def do_plymouth(msg):
|
||||
# type: (str) -> None
|
||||
|
@ -92,13 +154,21 @@ def do_plymouth(msg):
|
|||
logging.debug("Running plymouth --text")
|
||||
subprocess.call(["/bin/plymouth", "message", "--text", line])
|
||||
|
||||
def do_plymouth_splash():
|
||||
if os.path.exists("/bin/plymouth"):
|
||||
logging.debug("Running plymouth --splash")
|
||||
subprocess.run(["/sbin/plymouthd", "--mode=shutdown","--attach-to-session"])
|
||||
#subprocess.run(["/sbin/plymouthd", "--mode=update","--attach-to-session"])
|
||||
#subprocess.run(["/bin/plymouth","--update=kylin update"])
|
||||
subprocess.Popen(["/bin/plymouth", "show-splash","--wait"])
|
||||
subprocess.call(["/bin/plymouth","system-update","--progress=0"])
|
||||
|
||||
def log_msg(msg, level=logging.WARN):
|
||||
# type: (str, int) -> None
|
||||
""" helper that will print msg to usplash, plymouth, console """
|
||||
logging.log(level, msg)
|
||||
do_plymouth(msg)
|
||||
do_usplash(msg)
|
||||
#do_usplash(msg)
|
||||
|
||||
|
||||
def log_progress():
|
||||
|
@ -131,14 +201,79 @@ def signal_stop_unattended_upgrade():
|
|||
def exit_log_result(success):
|
||||
if success:
|
||||
log_msg(_("All upgrades installed"), logging.INFO)
|
||||
os._exit(0)
|
||||
sys.exit(0)
|
||||
else:
|
||||
log_msg(_("Unattended-upgrades stopped. There may be upgrades"
|
||||
" left to be installed in the next run."), logging.INFO)
|
||||
os._exit(1)
|
||||
sys.exit(1)
|
||||
|
||||
# 检查时间安全性 -- minute > 59; hour > 23;
|
||||
def check_time_safety(inTime):
|
||||
if inTime['m'] > 59 :
|
||||
inTime['h'] = inTime['h'] + inTime['m']//60
|
||||
inTime['m'] = inTime['m']%60
|
||||
|
||||
if inTime['h'] > 23 :
|
||||
inTime['h'] = inTime['h'] - 24
|
||||
|
||||
outTime = inTime
|
||||
return outTime
|
||||
|
||||
# 时间添加随机数
|
||||
def convert_time_by_random(inTime, inRandom):
|
||||
diff = random.randint(0,inRandom)
|
||||
inTime['h']=inTime['h'] + diff // 60
|
||||
inTime['m']=inTime['m'] + diff % 60
|
||||
outTime = check_time_safety(inTime)
|
||||
return outTime
|
||||
|
||||
class TimerThread(threading.Thread):
|
||||
def __init__(self, scheduler):
|
||||
threading.Thread.__init__(self)
|
||||
self.scheduler = scheduler
|
||||
def run(self):
|
||||
self.scheduler.start()
|
||||
|
||||
|
||||
|
||||
class UnattendedUpgradesShutdown():
|
||||
# 加载配置文件 unattended-upgrades-policy.conf
|
||||
def loadcfg(self):
|
||||
if os.path.isfile(UNATTENDED_UPGRADE_POLICY_FILE_PATH):
|
||||
self.preDownload = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_PREDOWNLOAD)
|
||||
self.autoUpgrade = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_AUTOUPGRADE)
|
||||
self.download_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_MODE)
|
||||
self.install_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_INSTALL_MODE)
|
||||
download_time = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_TIME)
|
||||
timelist = download_time.split(':')
|
||||
if len(timelist) != TimeElement.TIME_NUM:
|
||||
logging.debug("unattended-upgrades-policy.conf time err %s",download_time)
|
||||
return
|
||||
# 检查 传入时间 安全性
|
||||
try:
|
||||
tmphour = int(timelist[TimeElement.TIME_HOUR])
|
||||
except ValueError:
|
||||
logging.debug("unattended-upgrades-policy.conf download_time h error")
|
||||
return
|
||||
try:
|
||||
tmpminute = int(timelist[TimeElement.TIME_MINUTE])
|
||||
except ValueError:
|
||||
logging.debug("unattended-upgrades-policy.conf download_time m error")
|
||||
return
|
||||
|
||||
self.download_time['h'] = tmphour
|
||||
self.download_time['m'] = tmpminute
|
||||
self.download_time_r = convert_time_by_random(self.download_time, DOWNLOAD_RANDOM)
|
||||
self.install_time['h'] = self.download_time_r['h']
|
||||
self.install_time['m'] = self.download_time_r['m'] + INTERVAL_DOWN_INSTALL
|
||||
self.install_time_r = convert_time_by_random(self.install_time, INSTALL_RANDOM)
|
||||
logging.debug("upgrade time: [%d:%d] [%d:%d] predown[%s] autoupgrade[%s] d-mode[%s] i-mode[%s]",
|
||||
self.download_time_r['h'], self.download_time_r['m'],self.install_time_r['h'],self.install_time_r['m'],
|
||||
self.preDownload, self.autoUpgrade, self.download_mode, self.install_mode)
|
||||
else:
|
||||
logging.debug("unattended-upgrades-policy.conf not exist")
|
||||
|
||||
def __init__(self, options):
|
||||
# type: (Values) -> None
|
||||
|
@ -153,6 +288,18 @@ class UnattendedUpgradesShutdown():
|
|||
self.lock_was_taken = False
|
||||
self.signal_sent = False
|
||||
self.stop_signal_received = Event()
|
||||
self.download_mode = DownloadMode.TIMING_DOWNLOAD.value #下载模式
|
||||
self.install_mode = InstallMode.TIMING_INSTALL.value #安装模式
|
||||
self.download_time = {'h':9, 'm':0} #定时下载时间 09:00
|
||||
self.install_time = {'h':12, 'm':0} #定时安装时间 12:00
|
||||
self.download_time_r = convert_time_by_random(self.download_time, DOWNLOAD_RANDOM) #随机化定时下载时间
|
||||
self.install_time_r = convert_time_by_random(self.install_time, INSTALL_RANDOM) #随机化定时安装时间
|
||||
self.preDownload = False #预下载开关
|
||||
self.autoUpgrade = True #自动更新开关
|
||||
self.download_job = None
|
||||
self.install_job = None
|
||||
self.scheduler = BlockingScheduler()
|
||||
|
||||
try:
|
||||
hasattr(GLib, "MainLoop")
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
|
@ -164,8 +311,20 @@ class UnattendedUpgradesShutdown():
|
|||
logging.warning("Could not get delay inhibitor lock")
|
||||
self.inhibit_lock = None
|
||||
self.logind_proxy = None
|
||||
self.update_proxy = None
|
||||
self.wait_period = min(3, self.get_inhibit_max_delay() / 3)
|
||||
self.preparing_for_shutdown = False
|
||||
self.loadcfg()
|
||||
|
||||
def get_update_proxy(self):
|
||||
if not self.update_proxy:
|
||||
bus = dbus.SystemBus()
|
||||
self.update_proxy = bus.get_object('com.kylin.systemupgrade','/com/kylin/systemupgrade')
|
||||
return self.update_proxy
|
||||
|
||||
def get_update_interface(self):
|
||||
self.update_interface = dbus.Interface(self.update_proxy,dbus_interface='com.kylin.systemupgrade.interface')
|
||||
return self.update_interface
|
||||
|
||||
def get_logind_proxy(self):
|
||||
""" Get logind dbus proxy object """
|
||||
|
@ -247,12 +406,55 @@ class UnattendedUpgradesShutdown():
|
|||
# TODO iter on sigterm and sighup, too
|
||||
time.sleep(self.wait_period)
|
||||
|
||||
# 定时下载 执行函数
|
||||
def timing_download(self):
|
||||
env = copy.copy(os.environ)
|
||||
logging.debug("starting unattended-upgrades in timing download mode")
|
||||
timing_download_ret = subprocess.run(["kylin-unattended-upgrade","--download-only"], env=env)
|
||||
if timing_download_ret.returncode == 0:
|
||||
logging.debug("kylin-unattended-upgrade download success.")
|
||||
else:
|
||||
logging.debug("kylin-unattended-upgrade download %d .",timing_download_ret.returncode)
|
||||
|
||||
# 定时安装 执行函数
|
||||
def timing_install(self):
|
||||
env = copy.copy(os.environ)
|
||||
logging.debug("starting unattended-upgrades in timing install mode")
|
||||
timing_install_ret = subprocess.run(["kylin-unattended-upgrade","--install-only","--mode=timing"], env=env)
|
||||
if timing_install_ret.returncode == 0:
|
||||
logging.debug("kylin-unattended-upgrade install success.")
|
||||
else:
|
||||
logging.debug("kylin-unattended-upgrade install %d .",timing_install_ret.returncode)
|
||||
|
||||
|
||||
def _wait_for_unattended_upgrade_finish(self):
|
||||
#read unattended-upgrade status
|
||||
status = ReadValueFromFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status")
|
||||
while (status != "idle"):
|
||||
ReadValueFromFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status")
|
||||
time.sleep(1)
|
||||
return 0
|
||||
|
||||
def _pause_timer(self):
|
||||
if self.download_job is not None:
|
||||
self.download_job.pause()
|
||||
|
||||
if self.install_job is not None:
|
||||
self.install_job.pause()
|
||||
|
||||
def _resume_timer(self):
|
||||
if self.download_job is not None:
|
||||
self.download_job.resume()
|
||||
|
||||
if self.install_job is not None:
|
||||
self.install_job.resume()
|
||||
|
||||
def run(self):
|
||||
""" delay shutdown and wait for PrepareForShutdown or other signals"""
|
||||
|
||||
# set signal handlers
|
||||
def signal_handler(signum, frame):
|
||||
# type: (object) -> None
|
||||
|
||||
logging.warning(
|
||||
"SIGTERM or SIGHUP received, stopping unattended-upgrades "
|
||||
"only if it is running")
|
||||
|
@ -270,13 +472,97 @@ class UnattendedUpgradesShutdown():
|
|||
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, sig,
|
||||
signal_handler, None, None)
|
||||
if self.options.wait_for_signal:
|
||||
def change_upgrade_policy_handler():
|
||||
if os.path.isfile(UNATTENDED_UPGRADE_POLICY_FILE_PATH):
|
||||
download_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_MODE)
|
||||
install_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_INSTALL_MODE)
|
||||
preDownload = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_PREDOWNLOAD)
|
||||
autoUpgrade = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_AUTOUPGRADE)
|
||||
|
||||
if autoUpgrade == FeatureSwitch.ON.value or preDownload == FeatureSwitch.ON.value: #open download timing
|
||||
download_time_tmp = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_TIME)
|
||||
timelist = download_time_tmp.split(':')
|
||||
if len(timelist) != TimeElement.TIME_NUM:
|
||||
logging.debug("unattended-upgrades-policy.conf time err %s",download_time_tmp)
|
||||
return
|
||||
# 检查 传入时间 安全性
|
||||
try:
|
||||
tmphour = int(timelist[TimeElement.TIME_HOUR])
|
||||
except ValueError:
|
||||
logging.debug("unattended-upgrades-policy.conf download_time h error")
|
||||
else:
|
||||
self.download_time['h'] = tmphour
|
||||
|
||||
try:
|
||||
tmpminute = int(timelist[TimeElement.TIME_MINUTE])
|
||||
except ValueError:
|
||||
logging.debug("unattended-upgrades-policy.conf download_time m error")
|
||||
else:
|
||||
self.download_time['m'] = tmpminute
|
||||
|
||||
self.download_time_r = convert_time_by_random(self.download_time, DOWNLOAD_RANDOM)
|
||||
if self.download_job is not None:
|
||||
self.download_job.remove()
|
||||
self.download_job = self.scheduler.add_job(self.timing_download, 'cron', hour=self.download_time_r['h'], minute=self.download_time_r['m'])
|
||||
else: #close download timing
|
||||
self.download_job.pause()
|
||||
|
||||
if autoUpgrade == FeatureSwitch.ON.value and install_mode == InstallMode.TIMING_INSTALL.value: #open install timing
|
||||
self.install_time['h'] = self.download_time_r['h']
|
||||
self.install_time['m'] = self.download_time_r['m'] + INTERVAL_DOWN_INSTALL
|
||||
self.install_time_r = convert_time_by_random(self.install_time, INSTALL_RANDOM)
|
||||
if self.install_job is not None:
|
||||
self.install_job.remove()
|
||||
self.install_job = self.scheduler.add_job(self.timing_install, 'cron', hour=self.install_time_r['h'], minute=self.install_time_r['m'])
|
||||
else: #close install timing
|
||||
self.install_job.pause()
|
||||
|
||||
if self.install_mode == InstallMode.BEFORE_SHUTDOWN_INSTALL.value:
|
||||
if self.install_job is not None:
|
||||
self.install_job.remove()
|
||||
logging.debug("install job removed,installation will conduct before shutdown")
|
||||
|
||||
logging.debug("upgrade time: [%d:%d] [%d:%d] predown[%s] autoupgrade[%s] d-mode[%s] i-mode[%s]",
|
||||
self.download_time_r['h'], self.download_time_r['m'],self.install_time_r['h'],self.install_time_r['m'],
|
||||
self.preDownload, self.autoUpgrade, self.download_mode, self.install_mode)
|
||||
|
||||
else:
|
||||
logging.debug("unattended-upgrades-policy.conf not exist")
|
||||
|
||||
def upgrade_all_now_handler():
|
||||
self._wait_for_unattended_upgrade_finish()
|
||||
self._pause_timer()
|
||||
env = copy.copy(os.environ)
|
||||
retdownload = subprocess.run(["kylin-unattended-upgrade","--download-only"], env=env)
|
||||
retinstall = subprocess.run(["kylin-unattended-upgrade","--install-only"], env=env)
|
||||
self._resume_timer()
|
||||
if retdownload == 0 and retinstall == 0:
|
||||
return True
|
||||
|
||||
|
||||
def prepare_for_shutdown_handler(active):
|
||||
""" Handle PrepareForShutdown() """
|
||||
if not active:
|
||||
logging.warning("PrepareForShutdown(false) received, "
|
||||
"this should not happen")
|
||||
# PrepareForShutdown arrived, starting final iterations
|
||||
self.start_iterations()
|
||||
self.install_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH,POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY,AUTO_UPGRADE_POLICY_OPTION_INSTALL_MODE)
|
||||
if self.install_mode == InstallMode.BEFORE_SHUTDOWN_INSTALL.value:
|
||||
if self.update_interface.GetConfigValue('InstallMode','shutdown_install'):
|
||||
#show plymouth splash if bsshutdown is set
|
||||
if os.path.exists('/var/lib/unattended-upgrades/OTA_PKGS_TO_INSTALL'):
|
||||
do_plymouth_splash()
|
||||
self.start_iterations()
|
||||
else:
|
||||
os._exit(0)
|
||||
else:
|
||||
os._exit(0)
|
||||
else:
|
||||
os._exit(0)
|
||||
self.get_update_proxy()
|
||||
self.get_update_interface()
|
||||
self.update_proxy.connect_to_signal("ChangeUpgradePolicy",change_upgrade_policy_handler)
|
||||
self.update_proxy.connect_to_signal("UpgradeAllNow",upgrade_all_now_handler)
|
||||
try:
|
||||
self.get_logind_proxy().connect_to_signal(
|
||||
"PrepareForShutdown", prepare_for_shutdown_handler)
|
||||
|
@ -295,6 +581,12 @@ class UnattendedUpgradesShutdown():
|
|||
logging.debug("Skip waiting for signals, starting operation "
|
||||
"now")
|
||||
self.start_iterations()
|
||||
|
||||
logging.debug("download time:[%d:%d] install time:[%d:%d]", self.download_time_r['h'], self.download_time_r['m'],self.install_time_r['h'],self.install_time_r['m'])
|
||||
|
||||
self.download_job = self.scheduler.add_job(self.timing_download, 'cron', hour=self.download_time_r['h'], minute=self.download_time_r['m'])
|
||||
self.install_job = self.scheduler.add_job(self.timing_install, 'cron', hour=self.install_time_r['h'], minute=self.install_time_r['m'])
|
||||
TimerThread(self.scheduler).start()
|
||||
GLib.MainLoop().run()
|
||||
|
||||
def try_iter_on_shutdown(self):
|
||||
|
@ -318,14 +610,15 @@ class UnattendedUpgradesShutdown():
|
|||
not self.options.stop_only
|
||||
and not self.stop_signal_received.is_set()
|
||||
and self.apt_pkg_reinit_done
|
||||
and apt_pkg.config.find_b(
|
||||
"Unattended-Upgrade::InstallOnShutdown", False))
|
||||
# and apt_pkg.config.find_b(
|
||||
# "Unattended-Upgrade::InstallOnShutdown", False)
|
||||
)
|
||||
if self.on_shutdown_mode:
|
||||
env = copy.copy(os.environ)
|
||||
env["UNATTENDED_UPGRADES_FORCE_INSTALL_ON_SHUTDOWN"] = "1"
|
||||
#env["UNATTENDED_UPGRADES_FORCE_INSTALL_ON_SHUTDOWN"] = "1"
|
||||
logging.debug("starting unattended-upgrades in shutdown mode")
|
||||
self.on_shutdown_mode_uu_proc = subprocess.Popen(
|
||||
["kylin-unattended-upgrade","--install-only"], env=env)
|
||||
["kylin-unattended-upgrade","--install-only","--mode=shutdown"], env=env)
|
||||
log_msg(_("Running unattended-upgrades in shutdown mode"))
|
||||
# run u-u, but switch to stopping when receiving stop signal
|
||||
# because it means shutdown progressed despite holding the lock
|
||||
|
@ -349,7 +642,8 @@ class UnattendedUpgradesShutdown():
|
|||
logging.warning(_(
|
||||
"Giving up on lockfile after %s minutes of delay"),
|
||||
self.max_delay / 60)
|
||||
sys.exit(1)
|
||||
os._exit(1)
|
||||
#sys.exit(1)
|
||||
|
||||
if not self.stop_signal_received.is_set():
|
||||
if self.try_iter_on_shutdown():
|
||||
|
@ -361,6 +655,7 @@ class UnattendedUpgradesShutdown():
|
|||
# exit here if there is no lock
|
||||
if res > 0:
|
||||
logging.debug("lock not taken")
|
||||
os._exit(0)
|
||||
if self.lock_was_taken:
|
||||
exit_log_result(self.signal_sent)
|
||||
else:
|
||||
|
|
|
@ -1,145 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
check_stamp()
|
||||
{
|
||||
stamp="$1"
|
||||
interval="$2"
|
||||
|
||||
if [ "$interval" = always ]; then
|
||||
debug_echo "check_stamp: ignoring time stamp file, interval set to always"
|
||||
# treat as enough time has passed
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$interval" = 0 ]; then
|
||||
debug_echo "check_stamp: interval=0"
|
||||
# treat as no time has passed
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$stamp" ]; then
|
||||
debug_echo "check_stamp: missing time stamp file: $stamp."
|
||||
# treat as enough time has passed
|
||||
return 0
|
||||
fi
|
||||
|
||||
# compare midnight today to midnight the day the stamp was updated
|
||||
stamp_file="$stamp"
|
||||
stamp=$(date --date="$(date -r "$stamp_file" --iso-8601)" +%s 2>/dev/null)
|
||||
if [ "$?" != "0" ]; then
|
||||
# Due to some timezones returning 'invalid date' for midnight on
|
||||
# certain dates (e.g. America/Sao_Paulo), if date returns with error
|
||||
# remove the stamp file and return 0. See coreutils bug:
|
||||
# http://lists.gnu.org/archive/html/bug-coreutils/2007-09/msg00176.html
|
||||
rm -f "$stamp_file"
|
||||
return 0
|
||||
fi
|
||||
|
||||
now=$(date --date="$(date --iso-8601)" +%s 2>/dev/null)
|
||||
if [ "$?" != "0" ]; then
|
||||
# As above, due to some timezones returning 'invalid date' for midnight
|
||||
# on certain dates (e.g. America/Sao_Paulo), if date returns with error
|
||||
# return 0.
|
||||
return 0
|
||||
fi
|
||||
|
||||
delta=$((now-stamp))
|
||||
|
||||
# Calculate the interval in seconds depending on the unit specified
|
||||
if [ "${interval%s}" != "$interval" ] ; then
|
||||
interval="${interval%s}"
|
||||
elif [ "${interval%m}" != "$interval" ] ; then
|
||||
interval="${interval%m}"
|
||||
interval=$((interval*60))
|
||||
elif [ "${interval%h}" != "$interval" ] ; then
|
||||
interval="${interval%h}"
|
||||
interval=$((interval*60*60))
|
||||
else
|
||||
interval="${interval%d}"
|
||||
interval=$((interval*60*60*24))
|
||||
fi
|
||||
|
||||
debug_echo "check_stamp: interval=$interval, now=$now, stamp=$stamp, delta=$delta (sec)"
|
||||
|
||||
# remove timestamps a day (or more) in the future and force re-check
|
||||
if [ "$stamp" -gt $((now+86400)) ]; then
|
||||
echo "WARNING: file $stamp_file has a timestamp in the future: $stamp"
|
||||
rm -f "$stamp_file"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ $delta -ge $interval ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
update_stamp()
|
||||
{
|
||||
stamp="$1"
|
||||
touch "$stamp"
|
||||
}
|
||||
|
||||
debug_echo()
|
||||
{
|
||||
# Display message if $VERBOSE >= 1
|
||||
if [ "$VERBOSE" -ge 1 ]; then
|
||||
echo "$1" 1>&2
|
||||
fi
|
||||
}
|
||||
|
||||
# ------------------------ main ----------------------------
|
||||
|
||||
VERBOSE=5
|
||||
debug_echo "verbose level $VERBOSE"
|
||||
|
||||
# Global current time in seconds since 1970-01-01 00:00:00 UTC
|
||||
now=$(date +%s)
|
||||
|
||||
KylinAutodownloadInterval=7
|
||||
KylinAutoInstallInterval=7
|
||||
|
||||
# check if we actually have to do anything that requires locking the cache
|
||||
if [ $KylinAutodownloadInterval = always ] ||
|
||||
[ $KylinAutoInstallInterval = always ] ; then
|
||||
:
|
||||
elif [ $KylinAutodownloadInterval = 0 ] &&
|
||||
[ $KylinAutoInstallInterval = 0 ] ; then
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$1" = "download" ] || [ -z "$1" ] ; then
|
||||
|
||||
# download all upgradeable packages (if it is requested)
|
||||
DOWNLOAD_STAMP=/var/lib/apt/periodic/kylin-auto-download-stamp
|
||||
if which kylin-unattended-upgrade >/dev/null 2>&1 && check_stamp $DOWNLOAD_STAMP $KylinAutodownloadInterval; then
|
||||
if kylin-unattended-upgrade --download-only; then
|
||||
update_stamp $DOWNLOAD_STAMP
|
||||
debug_echo "kylin-autoupdate-download (success)"
|
||||
else
|
||||
debug_echo "kylin-autoupdate-download (error)"
|
||||
fi
|
||||
else
|
||||
debug_echo "kylin-autoupdate-download (not run)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" = "install" ] || [ -z "$1" ] ; then
|
||||
# auto upgrade all upgradeable packages
|
||||
INSTALL_STAMP=/var/lib/apt/periodic/kylin-auto-install-stamp
|
||||
if which kylin-unattended-upgrade >/dev/null 2>&1 && check_stamp $INSTALL_STAMP $KylinAutoInstallInterval; then
|
||||
if kylin-unattended-upgrade --install-only; then
|
||||
update_stamp $INSTALL_STAMP
|
||||
debug_echo "kylin-autoupdate-install (success)"
|
||||
else
|
||||
debug_echo "kylin-autoupdate-install (error)"
|
||||
fi
|
||||
else
|
||||
debug_echo "kylin-autoupdate-install (not run)"
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
#
|
|
@ -1,10 +0,0 @@
|
|||
[Unit]
|
||||
Description=Daily auto-download activities
|
||||
ConditionACPower=true
|
||||
After=network.target network-online.target systemd-networkd.service NetworkManager.service connman.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStartPre=-/usr/lib/apt/apt-helper wait-online
|
||||
ExecStart=/usr/bin/unattended-upgrades-daily download
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
[Unit]
|
||||
Description=Daily auto-download activities
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 10:00
|
||||
RandomizedDelaySec=1h
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
[Unit]
|
||||
Description=Daily auto-upgrade activities
|
||||
ConditionACPower=true
|
||||
#After=network.target network-online.target systemd-networkd.service NetworkManager.service connman.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/unattended-upgrades-daily install
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
[Unit]
|
||||
Description=Daily auto-upgrade activities
|
||||
After=unattended-upgrades-download.timer
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 14:00
|
||||
RandomizedDelaySec=5m
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
|
Loading…
Reference in New Issue