kylin-system-updater/unattended-upgrades/kylin-unattended-upgrade-sh...

1241 lines
56 KiB
Python

#!/usr/bin/python3
# Copyright (c) 2009-2018 Canonical Ltd
#
# AUTHOR:
# Michael Vogt <mvo@ubuntu.com>
# Balint Reczey <rbalint@ubuntu.com>
#
# unattended-upgrade-shutdown - helper that checks if a
# unattended-upgrade is in progress and waits until it exists
#
# This file is part of unattended-upgrades
#
# unattended-upgrades 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.
#
# unattended-upgrades 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 unattended-upgrades; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
import copy
import dbus
import signal
import sys
import time
import datetime
import logging
import logging.handlers
import gettext
import subprocess
import os.path
import os
import configparser
import psutil
from pytz import timezone
# for dbus signal handling
try:
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GLib
except ImportError:
pass
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
from apscheduler.schedulers.background import BackgroundScheduler
import random
import threading
import re
try:
import apt_pkg
except Exception:
# if there is no python-apt no unattended-upgrades can run so not
# need to stop the shutdown
logging.exception("importing of apt_pkg failed, exiting")
sys.exit(0)
# progress information is written here
PROGRESS_LOG = "/var/run/unattended-upgrades.progress"
PID_FILE = "/var/run/unattended-upgrades.pid"
LOCK_FILE = "/var/run/kylin-unattended-upgrades.lock"
PKGS_TO_INSTALL_FLAG_FILE="/var/lib/unattended-upgrades/OTA_PKGS_TO_INSTALL"
TIME_STAMP = "/var/lib/unattended-upgrades/unattended-upgrades-timestamp"
OTA_PKGS_TO_INSTALL_LIST="/var/lib/unattended-upgrades/ota_pkgs_to_install_list"
## 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"
AUTO_UPGRADE_POLICY_OPTION_UPGRADE_INTERVAL = "upgradeInverval"
INTERVAL_DOWN_INSTALL = 120 # 下载安装的间隔 分钟
INSTALL_RANDOM = 5 # 安装时间随机数范围0-INSTALL_RANDOM 分钟
DOWNLOAD_RANDOM = 180 # 下载时间随机数范围0-DOWNLOAD_RANDOM 分钟
PREDOWNLOAD_RANDOM = 180
class FeatureSwitch(Enum):
ON = 'on'
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'
UNATTENDED_UPGRADE_TIMESTAMP = "/var/lib/unattended-upgrades/unattended-upgrades-timestamp"
flag_file_list = ["/var/lib/unattended-upgrades/OTA_PKGS_TO_INSTALL",\
"/var/lib/kylin-auto-upgrade/kylin-autoupgrade.conf","/tmp/notify.pid"]
def reload_options_config():
#添加默认保留旧配置
apt_pkg.config["DPkg::Options::"] = "--force-confold"
options_new = list(set(apt_pkg.config.value_list("DPkg::Options")))
for option in ("--force-confnew","--force-confdef"):
if option in options_new:
options_new.remove(option)
#清除所有配置重新加载
apt_pkg.config.clear("DPkg::Options")
for option in options_new:
apt_pkg.config["DPkg::Options::"] = option
#去除安装推荐和建议的软件包
if apt_pkg.config.find_b("APT::Install-Recommends",False) == True:
apt_pkg.config.clear("APT::Install-Recommends")
if apt_pkg.config.find_b("APT::Install-Suggests",False) == True:
apt_pkg.config.clear("APT::Install-Suggests")
if apt_pkg.config.find("Dir::Etc::sourceparts","")!="":
apt_pkg.config["Dir::Etc::sourceparts"]=""
apt_pkg.init_system()
def get_mavis_capacity():
batterycapacity = 100
try:
with open("/sys/class/power_supply/BAT1/capacity", 'r') as f:
batterycapacity = int(f.readline())
except:
logging.error("no battery device")
return batterycapacity
def is_dpkg_journal_dirty():
# type: () -> bool
"""
Return True if the dpkg journal is dirty
(similar to debSystem::CheckUpdates)
"""
logging.debug("checking whether dpkg journal is dirty")
d = os.path.join("/var/lib/dpkg/",
#os.path.dirname(apt_pkg.config.find_file("Dir::State::status")),
"updates")
for f in os.listdir(d):
if re.match("[0-9]+", f) or re.match("tmp.i",f):
return True
return False
def get_abnormally_installed_pkg_count():
output = subprocess.check_output('dpkg -l|grep ^i[^i]|wc -l',shell=True)
return output.decode().strip()
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].strip('"')})
except Exception as e:
pass
if 'SUB_PROJECT_CODENAME' not in osreleasedict.keys():
osreleasedict.update({'SUB_PROJECT_CODENAME':''})
return osreleasedict
def FindRuningUnattendedUpgrades():
if os.path.exists(PID_FILE):
pid = open(PID_FILE).readline().strip()
logging.info("runing unattended-upgrades pid:%s"%pid)
try:
ps = psutil.Process(int(pid))
logging.debug("process name:%s,process status:%s"%(ps.name(),ps.status()))
return ps.is_running()
except Exception as e:
logging.error(e)
return False
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 ''
return value
def WriteValueToFile(file,section,option,value):
config=configparser.ConfigParser(allow_no_value=True)
config.add_section(section)
config.set(section,option,value)
config.write(open(file,"w"))
def clean_flag_files(filelist):
WriteValueToFile(UNATTENDED_UPGRADE_CONFIG_FILE_PATH,"UNATTENDED_UPGRADE","autoupdate_run_status","idle")
for file in filelist:
if os.path.exists(file):
os.remove(file)
def init():
if not os.path.exists(NOTIFICATION_PIPE):
os.mkfifo(NOTIFICATION_PIPE)
def get_random_time(stime,random_range):
now = datetime.datetime.now()
delta = random.randint(0,random_range)
actual_time = now + datetime.timedelta(minutes=delta)
try:
start_time = datetime.datetime.strptime(stime,"%H:%M")
start=datetime.datetime(now.year,now.month,now.day,start_time.hour,start_time.minute,0,0)
actual_time = start+datetime.timedelta(minutes=delta)
except Exception as e:
logging.error(e)
return actual_time
def task(task):
env = copy.copy(os.environ)
cmd = "date"
if task in ["predownload","download"]:
cmd = "kylin-unattended-upgrade --download-only"
elif task == "install":
cmd = "kylin-unattended-upgrade --install-only --mode=timing"
elif task == "download_and_install":
cmd = "kylin-unattended-upgrade --download-only&&kylin-unattended-upgrade --install-only --mode=timing"
#do not check updgrade period when download and install
else:
pass
ret = subprocess.run([cmd], shell=True,env=env)
logging.debug("task:%s return code:%d"%(task,ret.returncode))
return ret.returncode
def background_scheduler_init(background_scheduler):
background_scheduler.start()
random_time = get_random_time(autoupgradepolicy.GetOptionValue('downloadTime'),DOWNLOAD_RANDOM)
background_scheduler.add_job(task,'cron', args=['download'],id='download', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
random_time = random_time + datetime.timedelta(minutes=INTERVAL_DOWN_INSTALL)
background_scheduler.add_job(task,'cron', args=['install'],id='install', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
random_time = get_random_time(autoupgradepolicy.GetOptionValue('preDownloadTime'),PREDOWNLOAD_RANDOM)
background_scheduler.add_job(task,'cron', args=['predownload'],id='predownload', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
if autoupgradepolicy.GetOptionValue('autoUpgradeState') == 'on':
if autoupgradepolicy.GetOptionValue('downloadMode') != 'timing':
background_scheduler.pause_job('download')
if autoupgradepolicy.GetOptionValue('installMode') != 'timing':
background_scheduler.pause_job('install')
else:
background_scheduler.pause_job('download')
background_scheduler.pause_job('install')
if autoupgradepolicy.GetOptionValue('preDownload') != 'on':
background_scheduler.pause_job('predownload')
joblist = background_scheduler.get_jobs()
for job in joblist:
logging.debug("job:%s,next run time:%s"%(job.id,job.next_run_time))
'''
def do_usplash(msg):
# type: (str) -> None
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
if os.path.exists("/bin/plymouth"):
for line in msg.split("\n"):
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)
def log_progress():
# type: () -> None
""" helper to log the install progress (if any) """
# wait a some seconds and try again
'''
msg = _("Unattended-upgrade in progress during shutdown, "
"please don't turn off the computer")
'''
# progress info
progress_file = PROGRESS_LOG
if os.path.exists(progress_file):
progress_text = open(progress_file).read()
logging.debug("progress text content %s"%progress_text)
if len(progress_text):
progress = int(float(progress_text))
subprocess.call(["/bin/plymouth","system-update","--progress=%d"%progress])
msg = "upgrage progress %s"%progress_text
log_msg(msg)
def signal_term_handler(signal,frame):
# type: (int, object) -> None
logging.warning("SIGTERM received, will stop")
os._exit(1)
def signal_stop_unattended_upgrade():
""" send SIGTERM to running unattended-upgrade if there is any """
pidfile = PID_FILE#"/var/run/unattended-upgrades.pid"
if os.path.exists(pidfile):
pid = int(open(pidfile).read())
logging.debug("found running unattended-upgrades pid %s" % pid)
try:
os.kill(pid, signal.SIGTERM)
except ProcessLookupError:
logging.debug("sending SIGTERM failed because unattended-upgrades "
"already stopped")
def exit_log_result(success):
if os.path.exists(PKGS_TO_INSTALL_FLAG_FILE):
os.remove(PKGS_TO_INSTALL_FLAG_FILE)
subprocess.call(["/bin/plymouth","system-update","--progress=100"])
time.sleep(3)
subprocess.run(["/bin/plymouth","quit","--retain-splash"])
if success:
logging.debug("All upgrades installed")
#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 KylinSystemUpdater:
def __init__(self) -> None:
DBusGMainLoop(set_as_default=True)
self.loop = GLib.MainLoop()
self.system_bus = dbus.SystemBus()
self.update_proxy = self.system_bus.get_object('com.kylin.systemupgrade','/com/kylin/systemupgrade')
self.update_interface = dbus.Interface(self.update_proxy,dbus_interface='com.kylin.systemupgrade.interface')
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)
class AutoUpgradePolicy():
def __init__(self) -> None:
self.autoupgradepolicy = {}
if os.path.exists(UNATTENDED_UPGRADE_POLICY_FILE_PATH):
config=configparser.ConfigParser(allow_no_value=True)
config.optionxform = str
config.read(UNATTENDED_UPGRADE_POLICY_FILE_PATH)
for option in config.options('autoUpgradePolicy'):
self.autoupgradepolicy.update({option:config['autoUpgradePolicy'][option]})
for key in self.autoupgradepolicy.keys():
logging.debug("%s:%s"%(key,self.autoupgradepolicy[key]))
def SetOptionValue(self,option,value):
self.autoupgradepolicy.update({option:value})
def GetOptionValue(self,option):
try:
return self.autoupgradepolicy[option]
except Exception:
return ''
def reload_config(self):
if os.path.exists(UNATTENDED_UPGRADE_POLICY_FILE_PATH):
config=configparser.ConfigParser(allow_no_value=True)
config.optionxform = str
config.read(UNATTENDED_UPGRADE_POLICY_FILE_PATH)
for option in config.options('autoUpgradePolicy'):
self.autoupgradepolicy.update({option:config['autoUpgradePolicy'][option]})
for key in self.autoupgradepolicy.keys():
logging.debug("%s:%s"%(key,self.autoupgradepolicy[key]))
class UnattendedUpgradesShutdown():
# 加载配置文件 unattended-upgrades-policy.conf
'''
def loadcfg(self):
if os.path.exists(UNATTENDED_UPGRADE_POLICY_FILE_PATH):
self.preDownload = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_PREDOWNLOAD)
self.autoUpgrade = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_AUTOUPGRADE)
self.download_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_MODE)
self.install_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_INSTALL_MODE)
download_time = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_TIME)
# self.download_random = int(kylin_system_updater.GetConfigValue('AutoUpgradeConfig','downloadRandom')[1])
# self.upgrade_interval = int(kylin_system_updater.GetConfigValue('AutoUpgradeConfig','upgradeInterval')[1])
# logging.info("download random:%s,upgrade interval:%s"%(self.download_random,self.upgrade_interval))
# upgradeInterval = int(ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, 'upgradeInverval'))
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
self.download_time['h'] = 10
self.download_time['m'] = 0
self.download_time_r = convert_time_by_random(self.download_time, 5)
logging.debug("upgrade time: [%d] [%d] predown[%s] autoupgrade[%s] d-mode[%s] i-mode[%s]",
self.download_time_r['h'], self.download_time_r['m'],self.preDownload, self.autoUpgrade, \
self.download_mode, self.install_mode)
return
timelist = download_time.strip().split(':')
if len(timelist) != TimeElement.TIME_NUM:
logging.debug("unattended-upgrades-policy.conf time err %s",download_time)
return
# 检查 传入时间 安全性
try:
tmphour = int(timelist[TimeElement.TIME_HOUR])
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, self.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")
return
'''
def __init__(self, options):
# type: (Values) -> None
self.options = options
self.max_delay = options.delay * 60
self.mainloop = GLib.MainLoop()
self.iter_timer_set = False
self.apt_pkg_reinit_done = None
self.shutdown_pending = False
self.on_shutdown_mode = None
self.on_shutdown_mode_uu_proc = None
self.start_time = None
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 = 'off' #预下载开关
self.autoUpgrade = 'off' #自动更新开关
self.download_job = None
self.install_job = None
self.startup_download_job = None
self.scheduler = BlockingScheduler(timezone = "Asia/Shanghai")
'''
try:
hasattr(GLib, "MainLoop")
DBusGMainLoop(set_as_default=True)
except NameError:
logging.error("DBusGMainLoop error")
pass
try:
self.inhibit_lock = self.get_inhibit_shutdown_lock()
except dbus.exceptions.DBusException:
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 set_max_inhibit_time(self,time):
login_proxy = self.get_logind_proxy()
#首先设置systemd默认延长时间为1800
try:
getter_interface = dbus.Interface(
login_proxy,
dbus_interface='org.freedesktop.login1.Manager')
ret = getter_interface.SetInhibitDelayMaxSec(time)
except Exception as e:
logging.error(e)
'''
def get_logind_proxy(self):
""" Get logind dbus proxy object """
if not self.logind_proxy:
bus = dbus.SystemBus()
if self.inhibit_lock is None:
# try to get inhibit_lock or throw exception quickly when
# logind is down
self.inhibit_lock = self.get_inhibit_shutdown_lock()
self.logind_proxy = bus.get_object(
'org.freedesktop.login1', '/org/freedesktop/login1')
return self.logind_proxy
def get_inhibit_shutdown_lock(self):
""" Take delay inhibitor lock """
bus = dbus.SystemBus()
return bus.call_blocking(
'org.freedesktop.login1', '/org/freedesktop/login1',
'org.freedesktop.login1.Manager', 'Inhibit', 'ssss',
('shutdown', 'Unattended Upgrades Shutdown',
_('Stop ongoing upgrades or perform upgrades before shutdown'),
'delay'), timeout=2.0)
def get_inhibit_max_delay(self):
try:
logind_proxy = self.get_logind_proxy()
getter_interface = dbus.Interface(
logind_proxy,
dbus_interface='org.freedesktop.DBus.Properties')
return (getter_interface.Get(
"org.freedesktop.login1.Manager", "InhibitDelayMaxUSec")
/ (1000 * 1000))
except dbus.exceptions.DBusException:
return 3
def is_preparing_for_shutdown(self):
if not self.shutdown_pending:
try:
logind_proxy = self.get_logind_proxy()
getter_interface = dbus.Interface(
logind_proxy,
dbus_interface='org.freedesktop.DBus.Properties')
self.shutdown_pending = getter_interface.Get(
"org.freedesktop.login1.Manager", "PreparingForShutdown")
except dbus.exceptions.DBusException:
return False
return self.shutdown_pending
def start_iterations(self):
while self.iter():
time.sleep(1)
'''
if not self.iter_timer_set:
try:
GLib.timeout_add(self.wait_period * 1000, self.iter)
# schedule first iteration immediately
GLib.timeout_add(0, lambda: self.iter() and False)
except NameError:
pass
'''
return True
'''
def run_polling(self, signal_handler):
logging.warning(
_("Unable to monitor PrepareForShutdown() signal, polling "
"instead."))
logging.warning(
_("To enable monitoring the PrepareForShutdown() signal "
"instead of polling please install the python3-gi package"))
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGHUP, signal_handler)
# poll for PrepareForShutdown then run final iterations
if self.options.wait_for_signal:
logging.debug("Waiting for signal to start operation ")
while (not self.stop_signal_received.is_set()
and not self.is_preparing_for_shutdown()):
self.stop_signal_received.wait(self.wait_period)
else:
logging.debug("Skip waiting for signals, starting operation "
"now")
while not self.iter():
# TODO iter on sigterm and sighup, too
time.sleep(self.wait_period)
'''
# 定时下载 执行函数
def timing_download(self):
env = copy.copy(os.environ)
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):
max_wait_time = 300
wait_time = 0
#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)
wait_time += 1
if wait_time >max_wait_time:
logging.info("wait for uu time out")
return
return 0
def _pause_timer(self):
if self.download_job is not None:
self.download_job.pause()
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"""
# if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
# pass
# elif time.time() - float(time_stamp) < float(upgrade_interval):
# time_str1 = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(float(time_stamp)))
# time_str2 = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))
# logging.info("upgrade interval not satisfied:%s-%s"%(time_str1,time_str2))
# return 0
# set signal handlers
'''
def signal_handler(signum, frame):
logging.warning(
"SIGTERM or SIGHUP received, stopping unattended-upgrades "
"only if it is running")
self.stop_signal_received.set()
#self.start_iterations()
# fall back to polling without GLib
try:
hasattr(GLib, "MainLoop")
except NameError:
logging.error("MainLoop Not Found")
#self.run_polling(signal_handler)
return
for sig in (signal.SIGTERM, signal.SIGHUP):
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, sig,
signal_handler, None, None)
'''
if self.options.wait_for_signal:
def change_upgrade_policy_handler():
if os.path.exists(UNATTENDED_UPGRADE_POLICY_FILE_PATH):
autoupgradepolicy.reload_config()
if autoupgradepolicy.GetOptionValue('autoUpgradeState') == 'on':
random_time = get_random_time(autoupgradepolicy.GetOptionValue('downloadTime'),DOWNLOAD_RANDOM)
if autoupgradepolicy.GetOptionValue('downloadMode') == 'timing':
background_scheduler.add_job(task,'cron', args=['download'],id='download', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
if autoupgradepolicy.GetOptionValue('installMode') == 'timing':
random_time = random_time + datetime.timedelta(minutes=INTERVAL_DOWN_INSTALL)
background_scheduler.add_job(task,'cron', args=['install'],id='install', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
else:
background_scheduler.pause_job('download')
background_scheduler.pause_job('install')
if autoupgradepolicy.GetOptionValue('preDownload') == 'on':
random_time = get_random_time(autoupgradepolicy.GetOptionValue('preDownloadTime'),PREDOWNLOAD_RANDOM)
background_scheduler.add_job(task,'cron', args=['predownload'],id='download', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
else:
background_scheduler.pause_job('predownload')
joblist = background_scheduler.get_jobs()
for job in joblist:
logging.debug("job:%s,next run time:%s"%(job.id,job.next_run_time))
'''
self.download_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_MODE)
self.install_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_INSTALL_MODE)
self.preDownload = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_PREDOWNLOAD)
self.autoUpgrade = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_AUTOUPGRADE)
self.download_random = int(kylin_system_updater.GetConfigValue('AutoUpgradeConfig','downloadRandom')[1])
self.upgrade_interval = int(kylin_system_updater.GetConfigValue('AutoUpgradeConfig','upgradeInterval')[1])
download_time = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_DOWNLOAD_TIME)
timelist = download_time.strip().split(':')
if len(timelist) != TimeElement.TIME_NUM:
logging.debug("unattended-upgrades-policy.conf time err %s",download_time)
return
# 检查 传入时间 安全性
try:
tmphour = int(timelist[TimeElement.TIME_HOUR])
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, self.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.info("download random:%d,upgrade interval:%d"%(self.download_random,self.upgrade_interval))
if self.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, self.download_random)
try:
if self.download_job is not None:
self.download_job.remove()
except Exception as e:
logging.error(e)
logging.info("pre-download time:%d:%d"%(self.download_time_r['h'], self.download_time_r['m']))
self.download_job = self.scheduler.add_job(self.timing_download, 'cron', hour=self.download_time_r['h'], minute=self.download_time_r['m'])
elif self.preDownload == FeatureSwitch.OFF.value:
pass
else: #close download timing
try:
self.download_job.pause()
except Exception as e:
logging.error(e)
if self.autoUpgrade == FeatureSwitch.OFF.value:
logging.info("auto upgrade turned off,removing download and instal jobs...")
try:
if self.download_job.pending:
self.download_job.remove()
except Exception as e:
pass
# logging.error(e)
try:
if self.install_job.pending:
self.install_job.remove()
except Exception as e:
pass
# logging.error(e)
return
else:
if self.download_mode == DownloadMode.TIMING_DOWNLOAD.value:
try:
if self.download_job.pending:
self.download_job.remove()
except Exception as e:
pass
# logging.error(e)
logging.info("download time:%d:%d"%(self.download_time_r['h'], self.download_time_r['m']))
self.download_job = self.scheduler.add_job(self.timing_download, 'cron', hour=self.download_time_r['h'], minute=self.download_time_r['m'])
else:
try:
if self.download_job.pending:
self.download_job.remove()
except Exception as e:
pass
# logging.error(e)
if self.install_mode == InstallMode.TIMING_INSTALL.value:
try:
if self.install_job.pending:
self.install_job.remove()
except Exception as e:
pass
# logging.error(e)
logging.info("install time:%d:%d"%(self.install_time_r['h'], self.install_time_r['m']))
self.install_job = self.scheduler.add_job(self.timing_install, 'cron', hour=self.install_time_r['h'], minute=self.install_time_r['m'])
elif self.install_mode == InstallMode.BEFORE_SHUTDOWN_INSTALL.value:
try:
if self.install_job.pending:
self.install_job.remove()
except Exception as e:
pass
# logging.error(e)
logging.debug("install job removed,installation will conduct before shutdown")
else: #close install timing
try:
if self.download_job.pending:
self.install_job.remove()
except Exception as e:
pass
# logging.error(e)
logging.info("upgrade time: [%d:%d] [%d:%d] predown[%s] autoupgrade[%s] d-mode[%s] i-mode[%s]",
self.download_time_r['h'], self.download_time_r['m'],self.install_time_r['h'],self.install_time_r['m'],
self.preDownload, self.autoUpgrade, self.download_mode, self.install_mode)
'''
else:
logging.debug("unattended-upgrades-policy.conf not exist")
def upgrade_all_now_handler():
now=datetime.datetime.now()
random_time = now + datetime.timedelta(minutes=DOWNLOAD_RANDOM)
background_scheduler.add_job(task,'date', args=['download_and_install'],id='download', \
hour = random_time.hour,minute = random_time.minute,replace_existing=True)
joblist = background_scheduler.get_jobs()
for job in joblist:
logging.debug("job:%s,next run time:%s"%(job.id,job.next_run_time))
#self._wait_for_unattended_upgrade_finish()
'''
if FindRuningUnattendedUpgrades():
logging.warning("find runing unattended-upgrades,please wait")
return False
else:
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
else:
return False
'''
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.install_mode = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH,POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY,AUTO_UPGRADE_POLICY_OPTION_INSTALL_MODE)
autoUpgrade = ReadValueFromFile(UNATTENDED_UPGRADE_POLICY_FILE_PATH, POLICY_CONF_SECTION_AUTO_UPGRADE_POLICY, AUTO_UPGRADE_POLICY_OPTION_AUTOUPGRADE)
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
bat = get_mavis_capacity()
logging.info("battery capacity:%d"%bat)
if os.path.exists(PKGS_TO_INSTALL_FLAG_FILE) and bat >=25:
logging.info("mavis shutdown install")
do_plymouth_splash()
self.start_iterations()
logging.info("finished iteration")
elif autoUpgrade == FeatureSwitch.ON.value and self.install_mode == InstallMode.BEFORE_SHUTDOWN_INSTALL.value:
if self.update_interface.GetConfigValue('AutoUpgradeConfig','shutdown_install'):
#show plymouth splash if bsshutdown is set
if os.path.exists(PKGS_TO_INSTALL_FLAG_FILE):
do_plymouth_splash()
self.start_iterations()
logging.info("finished iteration")
else:
pass
self.mainloop.quit()
self.get_update_proxy()
self.get_update_interface()
self.update_proxy.connect_to_signal("ChangeUpgradePolicy",change_upgrade_policy_handler)
self.update_proxy.connect_to_signal("UpgradeAllNow",upgrade_all_now_handler)
try:
self.get_logind_proxy().connect_to_signal(
"PrepareForShutdown", prepare_for_shutdown_handler)
except dbus.exceptions.DBusException:
logging.warning(
_("Unable to monitor PrepareForShutdown() signal, polling "
"instead."))
logging.warning(
_("Maybe systemd-logind service is not running."))
# self.run_polling(signal_handler)
return
#self.set_max_inhibit_time(1800)
logging.debug("Waiting for signal to start operation ")
else:
# starting final iterations immediately
logging.debug("Skip waiting for signals, starting operation "
"now")
# self.start_iterations()
'''
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
logging.info("setting startup download timer")
GLib.timeout_add(300*1000, lambda: self.timing_download() and False)
#local_time =time.localtime(time.time()+300)
self.startup_download_job = self.scheduler.add_job(self.timing_download,'cron',hour=self.download_time_r['h'],minute = self.download_time_r['m'])
else:
if self.autoUpgrade == FeatureSwitch.ON.value:
logging.debug("download time:[%d:%d] install time:[%d:%d]", self.download_time_r['h'], self.download_time_r['m'],self.install_time_r['h'],self.install_time_r['m'])
self.download_job = self.scheduler.add_job(self.timing_download, 'cron', hour=self.download_time_r['h'], minute=self.download_time_r['m'])
self.install_job = self.scheduler.add_job(self.timing_install, 'cron', hour=self.install_time_r['h'], minute=self.install_time_r['m'])
elif self.autoUpgrade == FeatureSwitch.OFF.value:
logging.info("auto upgrade turned off")
'''
#TimerThread(self.scheduler).start()
self.mainloop.run()
logging.info("quit mainloop")
os._exit(0)
#GLib.MainLoop().run()
def try_iter_on_shutdown(self):
# check if we need to run unattended-upgrades on shutdown and if
# so, run it
try:
if self.apt_pkg_reinit_done is None:
logging.debug("Initializing apt_pkg configuration")
apt_pkg.init_config()
self.apt_pkg_reinit_done = True
except apt_pkg.Error as error:
# apt may be in a transient state due to unattended-upgrades
# running, thus assuming non shutdown mode is reasonable
logging.error(_("Apt returned an error thus shutdown mode is "
"disabled"))
logging.error(_("error message: '%s'"), error)
self.apt_pkg_reinit_done = False
if self.on_shutdown_mode is None:
self.on_shutdown_mode = True
#(
#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)
#)
if self.on_shutdown_mode:
env = copy.copy(os.environ)
#env["UNATTENDED_UPGRADES_FORCE_INSTALL_ON_SHUTDOWN"] = "1"
logging.info("starting unattended-upgrades in shutdown mode")
if FindRuningUnattendedUpgrades():
logging.warning("another unattended-upgrade is running , quit")
return False
self.on_shutdown_mode_uu_proc = subprocess.Popen(
["kylin-unattended-upgrade","--install-only","--mode=shutdown"], env=env)
#log_msg(_("Running unattended-upgrades in shutdown mode"))
# run u-u, but switch to stopping when receiving stop signal
# because it means shutdown progressed despite holding the lock
if self.on_shutdown_mode:
log_progress()
if self.on_shutdown_mode_uu_proc.poll() is not None:
# unattended-upgrades stopped on its own
#exit_log_result(True)
if os.path.exists(PKGS_TO_INSTALL_FLAG_FILE):
os.remove(PKGS_TO_INSTALL_FLAG_FILE)
subprocess.call(["/bin/plymouth","system-update","--progress=100"])
time.sleep(1)
subprocess.run(["/bin/plymouth","quit","--retain-splash"])
return False
else:
return True
return False
def iter(self):
'''
if self.start_time is None:
self.start_time = time.time()
logging.debug("Starting countdown of %s minutes",
self.max_delay / 60)
else:
if (time.time() - self.start_time) > self.max_delay:
logging.warning(_(
"Giving up on lockfile after %s minutes of delay"),
self.max_delay / 60)
#os._exit(1)
#sys.exit(1)
return False
if not self.stop_signal_received.is_set():
if self.try_iter_on_shutdown():
return True
else:
return False
# run monitoring and keep "UI" updated
res = apt_pkg.get_lock(self.options.lock_file)
logging.debug("get_lock returned %i" % res)
# 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:
sys.exit(0)
self.lock_was_taken = True
signal_stop_unattended_upgrade()
self.signal_sent = True
# show log
log_progress()
'''
return self.try_iter_on_shutdown()
#return True
def main():
# setup gettext
localesApp = "unattended-upgrades"
localesDir = "/usr/share/locale"
gettext.bindtextdomain(localesApp, localesDir)
gettext.textdomain(localesApp)
# use a normal logfile instead of syslog too as on shutdown its too
# easy to get syslog killed
logdir = "/var/log/kylin-unattended-upgrades/"
try:
apt_pkg.init_config()
# logdir = apt_pkg.config.find_dir(
# "Unattended-Upgrade::LogDir", logdir)
except apt_pkg.Error as error:
logging.error(_("Apt returned an error when loading configuration, "
"using default values"))
logging.error(_("error message: '%s'"), error)
parser = OptionParser()
parser.add_option("", "--debug",
action="store_true", dest="debug",
default=apt_pkg.config.find_b(
"Unattended-Upgrade::Debug", True),
help="print debug messages")
parser.add_option("", "--delay", default=25, type="int",
help="delay in minutes to wait for unattended-upgrades")
parser.add_option("", "--lock-file",
default="/var/run/kylin-unattended-upgrades.lock",
help="lock file location")
parser.add_option("", "--stop-only",
action="store_true", dest="stop_only", default=False,
help="only stop running unattended-upgrades, don't "
"start it even when "
"Unattended-Upgrade::InstallOnShutdown is true")
parser.add_option("", "--wait-for-signal",
action="store_true", dest="wait_for_signal",
default=False,
help="wait for TERM signal before starting operation")
(options, args) = parser.parse_args()
# setup logging
level = logging.INFO
if options.debug:
level = logging.DEBUG
if not os.path.exists('/var/lib/unattended-upgrades'):
os.makedirs('/var/lib/unattended-upgrades')
if not os.path.exists(logdir):
os.makedirs(logdir)
logfile = os.path.join(logdir, "unattended-upgrades-shutdown.log")
logging.basicConfig(filename=logfile,
level=level,
format="%(asctime)s %(levelname)s - %(message)s")
clean_flag_files(flag_file_list)
signal.signal(signal.SIGTERM, signal_term_handler)
signal.signal(signal.SIGHUP, signal.SIG_IGN)
# init()
UnattendedUpgradesShutdown(options).run()
if __name__ == "__main__":
parser = OptionParser()
parser.add_option("", "--debug",
action="store_true", dest="debug",
default=True,#apt_pkg.config.find_b(
#"Unattended-Upgrade::Debug", True),
help="print debug messages")
parser.add_option("", "--delay", default=25, type="int",
help="delay in minutes to wait for unattended-upgrades")
parser.add_option("", "--lock-file",
default="/var/run/kylin-unattended-upgrades.lock",
help="lock file location")
parser.add_option("", "--stop-only",
action="store_true", dest="stop_only", default=False,
help="only stop running unattended-upgrades, don't "
"start it even when "
"Unattended-Upgrade::InstallOnShutdown is true")
parser.add_option("", "--wait-for-signal",
action="store_true", dest="wait_for_signal",
default=False,
help="wait for TERM signal before starting operation")
(options, args) = parser.parse_args()
logdir = "/var/log/kylin-unattended-upgrades/"
# setup logging
level = logging.INFO
if options.debug:
level = logging.DEBUG
if not os.path.exists('/var/lib/unattended-upgrades'):
os.makedirs('/var/lib/unattended-upgrades')
if not os.path.exists(logdir):
os.makedirs(logdir)
logfile = os.path.join(logdir, "unattended-upgrades-shutdown.log")
logging.basicConfig(filename=logfile,
level=level,
format="%(asctime)s %(levelname)s - %(message)s")
logging.getLogger('apscheduler').setLevel(logging.DEBUG)
os_release_info = ReadOsRelease('/etc/os-release')
logging.info("project id:%s,sub-project id:%s"%(os_release_info['PROJECT_CODENAME'],os_release_info['SUB_PROJECT_CODENAME']))
time_stamp = "0"
if os.path.exists(TIME_STAMP):
with open(TIME_STAMP,'r') as f:
time_stamp = f.readline()
logging.info("time stamp:%s"%time_stamp)
# setup gettext
localesApp = "unattended-upgrades"
localesDir = "/usr/share/locale"
gettext.bindtextdomain(localesApp, localesDir)
gettext.textdomain(localesApp)
# use a normal logfile instead of syslog too as on shutdown its too
# easy to get syslog killed
try:
# apt_pkg.init_config()
reload_options_config()
# logdir = apt_pkg.config.find_dir(
# "Unattended-Upgrade::LogDir", logdir)
except apt_pkg.Error as error:
logging.error(_("Apt returned an error when loading configuration, "
"using default values"))
logging.error(_("error message: '%s'"), error)
clean_flag_files(flag_file_list)
signal.signal(signal.SIGTERM, signal_term_handler)
signal.signal(signal.SIGHUP, signal.SIG_IGN)
dpkg_fix=None
if os_release_info['PROJECT_CODENAME'] == 'V10SP1-edu' and os_release_info['SUB_PROJECT_CODENAME']=='mavis':
dpkg_journal_dirty = is_dpkg_journal_dirty()
logging.info("dpkg dirty:%s"%(dpkg_journal_dirty))
if dpkg_journal_dirty:
try:
with open(OTA_PKGS_TO_INSTALL_LIST,'r') as f:
pkgs = f.read()
ret = subprocess.run(["dpkg -i %s"%pkgs],shell=True,stdout=open(logfile,'a+'),stderr=open(logfile,'a+'))
except Exception as e:
logging.error(e)
if ret.returncode == 0:
logging.info("dpkg fix success")
subprocess.Popen('dbus-send --system --type=signal / com.kylin.update.notification.FixFinish', shell=True)
# dpkg_fix = subprocess.run("dpkg --configure -a",shell=True,stdout=open(logfile,'a+'),stderr=open(logfile,'a+'))
abnormal_pkg_count = get_abnormally_installed_pkg_count()
logging.info("abnormal pkg count:%s"%(abnormal_pkg_count))
if abnormal_pkg_count != '0':
apt_fix = subprocess.run("echo y|apt install -f",shell=True,stdout=open(logfile,'a+'),stderr=open(logfile,'a+'))
kylin_system_updater = KylinSystemUpdater()
autoupgradepolicy = AutoUpgradePolicy()
background_scheduler = BackgroundScheduler(timezone = "Asia/Shanghai")
background_scheduler_init(background_scheduler)
UnattendedUpgradesShutdown(options).run()
#main()