[yum-cvs] yum yum-updatesd.py,1.7,1.8
Jeremy Katz
katzj at linux.duke.edu
Fri May 19 21:39:18 UTC 2006
Update of /home/groups/yum/cvs/yum
In directory login1.linux.duke.edu:/tmp/cvs-serv16608
Modified Files:
yum-updatesd.py
Log Message:
a variety of things as I start to hook up proto-puplet
* some consistency fixes to make service names all edu.duke.linux.yum, object
paths differ between the signaller and the listener but that makes sense
* add a --no-fork mode so that you can use ctrl-c and hack on this more easily
* add a ShutDown method (disabled by default) since I was getting hit by
the sigint catcher a few times
* add a GetUpdatesInfo method to return the information on the available
updates. this should probably be changed to return the information in
an async fashion, but I'll get there
Index: yum-updatesd.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum-updatesd.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- yum-updatesd.py 8 May 2006 17:30:10 -0000 1.7
+++ yum-updatesd.py 19 May 2006 21:39:16 -0000 1.8
@@ -28,6 +28,7 @@
import dbus.glib
import gobject
import smtplib
+from optparse import OptionParser
from email.MIMEText import MIMEText
@@ -42,16 +43,15 @@
config_file = '/etc/yum/yum-updatesd.conf'
-
class YumDbusInterface(dbus.service.Object):
- def __init__(self, bus_name, object_path='/edu/duke/linux/yum/object'):
+ def __init__(self, bus_name, object_path='/UpdatesAvail'):
dbus.service.Object.__init__(self, bus_name, object_path)
- @dbus.service.signal('edu.duke.linux.Yum')
+ @dbus.service.signal('edu.duke.linux.yum')
def UpdatesAvailableSignal(self, message):
pass
- @dbus.service.signal('edu.duke.linux.Yum')
+ @dbus.service.signal('edu.duke.linux.yum')
def NoUpdatesAvailableSignal(self, message):
pass
@@ -59,7 +59,7 @@
class UDConfig(yum.config.BaseConfig):
"""Config format for the daemon"""
- run_interval = IntOption(3600)
+ run_interval = IntOption(10)
nonroot_workdir = Option("/var/tmp/yum-updatesd")
emit_via = ListOption(['dbus', 'email', 'syslog'])
email_to = Option("root at localhost")
@@ -71,12 +71,12 @@
class UpdatesDaemon(yum.YumBase):
- def __init__(self, opts):
+ def __init__(self, opts, dbusintf):
yum.YumBase.__init__(self)
self.opts = opts
self.doSetup()
- self.updatesCheck()
- self.doShutdown()
+
+ self.dbusintf = dbusintf
def log(self, num, msg):
#TODO - this should probably syslog
@@ -94,38 +94,54 @@
self.repos.setCacheDir(self.opts.nonroot_workdir)
self.doConfigSetup(fn=self.opts.yum_config)
- self.doLock(YUM_PID_FILE)
+
+ def refreshUpdates(self):
+ self.doLock(YUM_PID_FILE)
self.doRepoSetup()
self.doSackSetup()
self.doTsSetup()
self.doRpmDBSetup()
self.doUpdateSetup()
-
+
def updatesCheck(self):
+ try:
+ self.refreshUpdates()
+ except yum.Errors.LockError:
+ return True # just pass for now
+
updates = len(self.up.getUpdatesList())
obsoletes = len(self.up.getObsoletesTuples())
# this should check to see if opts.do_update is true or false
# right now just notify something/someone
- num_updates = updates+obsoletes
- self.emit(num_updates)
-
+ if not self.opts.do_update:
+ num_updates = updates+obsoletes
+ self.emitAvailable(num_updates)
- def doShutdown(self):
+ self.closeRpmDB()
self.doUnlock(YUM_PID_FILE)
- # close the rpmdb
- self.closeRpmDB()
- # delete the updates object
- if hasattr(self, 'up'):
- del self.up
- # delete the package sacks/repos
- if hasattr(self, 'pkgSack'):
- del self.pkgSack
- if hasattr(self, 'repos'):
- del self.repos
-
- def emit(self, num_updates):
+ return True
+
+ def getUpdateInfo(self):
+ # try to get the lock up to 10 times to get the explicitly
+ # asked for info
+ tries = 0
+ while tries < 10:
+ try:
+ self.doLock(YUM_PID_FILE)
+ break
+ except yum.Errors.LockError:
+ pass
+ time.sleep(1)
+
+ self.doTsSetup()
+ self.doRpmDBSetup()
+ self.doUpdateSetup()
+ self.doUnlock(YUM_PID_FILE)
+ return self.up.getUpdatesTuples()
+
+ def emitAvailable(self, num_updates):
"""method to emit a notice about updates"""
if 'dbus' in self.opts.emit_via:
self.emit_dbus(num_updates)
@@ -178,57 +194,65 @@
def emit_dbus(self, num_updates):
"""method to emit a dbus event for notice of updates"""
- # setup the dbus interface
- my_bus = dbus.SystemBus()
- name = dbus.service.BusName('edu.duke.linux.Yum', bus=my_bus)
- yum_dbus = YumDbusInterface(name)
+ if not self.dbusintf:
+ # FIXME: assert here ?
+ return
if num_updates > 0:
msg = "%d updates available" % num_updates
- yum_dbus.UpdatesAvailableSignal(msg)
+ self.dbusintf.UpdatesAvailableSignal(msg)
else:
msg = "No Updates Available"
- yum_dbus.NoUpdatesAvailableSignal(msg)
-
- del yum_dbus
- del name
- del my_bus
-
+ self.dbusintf.NoUpdatesAvailableSignal(msg)
+
class YumDbusListener(dbus.service.Object):
- def __init__(self, bus_name, object_path='/Updatesd'):
+ def __init__(self, updd, bus_name, object_path='/Updatesd'):
dbus.service.Object.__init__(self, bus_name, object_path)
+ self.updd = updd
+ self.allowshutdown = False
- @dbus.service.method("edu.duke.linux.yum.Updatesd")
- def CheckNow(self):
- run_update_check()
- return "check completed"
-
+ def doCheck(self):
+ self.updd.updatesCheck()
+ return False
+ @dbus.service.method("edu.duke.linux.yum")
+ def CheckNow(self):
+ # make updating checking asynchronous since we discover whether
+ # or not there are updates via a callback signal anyway
+ gobject.idle_add(self.doCheck)
+ return "check queued"
+
+ @dbus.service.method("edu.duke.linux.yum")
+ def ShutDown(self):
+ if not self.allowshutdown:
+ return False
+
+ # we have to do this in a callback so that it doesn't get
+ # sent back to the caller
+ gobject.idle_add(quit)
+ return True
+
+ @dbus.service.method("edu.duke.linux.yum")
+ def GetUpdateInfo(self):
+ # FIXME: should this be async?
+ upds = self.updd.getUpdateInfo()
+ return upds
-def run_update_check(opts=None):
-
- if not opts:
- confparser = IncludingConfigParser()
- opts = UDConfig()
-
- if os.path.exists(config_file):
- confparser.read(config_file)
-
- opts.populate(confparser, 'main')
-
- try:
- my = UpdatesDaemon(opts)
- except yum.Errors.YumBaseError, e:
- print >> sys.stderr, 'Error: %s' % e
- else:
- del my
-
- return True # has to be true or gobject will stop running it afaict
-
+def quit(*args):
+ sys.exit(0)
def main():
-
- if os.fork():
- sys.exit()
+ parser = OptionParser()
+ parser.add_option("-f", "--no-fork", action="store_true", default=False, dest="nofork")
+ (options, args) = parser.parse_args()
+
+ if not options.nofork:
+ if os.fork():
+ sys.exit()
+ fd = os.open("/dev/null", os.O_RDONLY)
+ os.dup2(fd, 0)
+ os.dup2(fd, 1)
+ os.dup2(fd, 2)
+ os.close(fd)
confparser = IncludingConfigParser()
opts = UDConfig()
@@ -237,14 +261,24 @@
confparser.read(config_file)
opts.populate(confparser, 'main')
+
+ if "dbus" in opts.emit_via:
+ # setup the dbus interfaces
+ bus = dbus.SystemBus()
+
+ name = dbus.service.BusName('edu.duke.linux.yum', bus=bus)
+ yum_dbus = YumDbusInterface(name)
+
+ updd = UpdatesDaemon(opts, yum_dbus)
+
+ name = dbus.service.BusName("edu.duke.linux.yum", bus=bus)
+ object = YumDbusListener(updd, name)
+ else:
+ updd = UpdatesDaemon(opts, None)
- bus = dbus.SystemBus()
- name = dbus.service.BusName("edu.duke.linux.yum.Updatesd", bus=bus)
- object = YumDbusListener(name)
-
- run_interval_ms = opts.run_interval * 1000 # get it into milliseconds for gobject
+ run_interval_ms = opts.run_interval * 1000 # needs to be in ms
- gobject.timeout_add(run_interval_ms, run_update_check)
+ gobject.timeout_add(run_interval_ms, updd.updatesCheck)
mainloop = gobject.MainLoop()
mainloop.run()
More information about the Yum-cvs-commits
mailing list