Viewing file: method.py (35.6 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# # method.py - abstraction of install method # # Copyright 2002, 2003 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # General Public License. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #
import os,sys,string,stat,exceptions import GroupSet import install import time from constants import * import GroupSet from config import get_fallback_mountpoint, install_pkgs
import kudzu import rpm import gtk import dbus from Progress import ProgressCanceled from rhpl.log import log import rhpl.diskutil as diskutil import rhpl.discid from rhpl.GenericError import * from rhpl.translate import _, N_ from CDDialog import CDDialog from size_string import size_string
global cdMntpt global currentCdDev cdMntpt = get_fallback_mountpoint() currentCdDev = None
class DepsCheckLoop (Exception): def __init__ (self, install_list, remove_list): exceptions.Exception.__init__(self) self.args = (install_list, remove_list) self.install_list = install_list self.remove_list = remove_list
class DepsCheckComps (Exception): def __init__ (self, failed_list, unremovable_list): exceptions.Exception.__init__(self) self.args = (failed_list, unremovable_list) self.failed_list = failed_list self.unremovable_list = unremovable_list
class UnresolvableDependencies (Exception): def __init__ (self, unresolvable_dependencies): exceptions.Exception.__init__(self) self.args = (unresolvable_dependencies) self.unresolvable_dependencies = unresolvable_dependencies
class NotImplemented (Exception): def __init__(self): exceptions.Exception.__init__(self) pass
# FIXME: ripped right out of anaconda, belongs in rhpl def getArch(): arch = os.uname()[4] if (len (arch) == 4 and arch[0] == 'i' and arch[2:4] == "86"): arch = "i386"
if arch == "sparc64": arch = "sparc"
if arch == "ppc64": arch = "ppc"
return arch
# format problems returned as a result of an rpm ts.run() operation def formatProblems(problems): spaceneeded = {} nodeneeded = {}
for (descr, (type, mount, need)) in problems: if type == rpm.RPMPROB_DISKSPACE: if spaceneeded.has_key (mount) and spaceneeded[mount] < need: spaceneeded[mount] = need else: spaceneeded[mount] = need elif type == rpm.RPMPROB_DISKNODES: if nodeneeded.has_key (mount) and nodeneeded[mount] < need: nodeneeded[mount] = need else: nodeneeded[mount] = need else: log ("WARNING: unhandled problem returned from " "transaction set type %d", type)
probs = "" if spaceneeded: probs = probs + _("You don't appear to have enough disk space " "to install the packages you've selected. " "You need more space on the following " "file systems:\n\n") probs = probs + ("%-15s %s\n") % (_("Mount Point"), _("Space Needed"))
for (mount, need) in spaceneeded.items (): need = size_string(need)
prob = "%-15s %s\n" % (mount, need) probs = probs + prob if nodeneeded: if probs: probs = probs + '\n' probs = probs + _("You don't appear to have enough file nodes " "to install the packages you've selected. " "You need more file nodes on the following " "file systems:\n\n") probs = probs + ("%-15s %s\n") % (_("Mount Point"), _("Nodes Needed"))
for (mount, need) in nodeneeded.items (): prob = "%-15s %d\n" % (mount, need) probs = probs + prob return probs
class InstallMethod: def __init__(self): self.pixmapPath = [] self.releaseName = '' self.discidPixmapPath = "/usr/share/pixmaps"
def getPixmapPath(self): return self.pixmapPath
def getPixmapFile(self, file, discid_only=0): if discid_only: file = self.discidPixmapPath + "/" + file if os.path.isfile (file): return file else: return None
for parent_path in self.getPixmapPath(): test_file = parent_path + "/" + file if os.path.isfile (test_file): return test_file
return None
def getReleaseName(self): return self.releaseName
def readCompsViaMethod(self, hdlist, update_method=None): raise NotImplemented
def readHeaders(self, update_method=None): raise NotImplemented
def getFilename(self, h, timer, installed = 0): raise NotImplemented
def unlinkFilename(self, fn): raise NotImplemented
def filesDone(self): raise NotImplemented
def isUpdateRPM(self, hdr): if (1000005 in hdr.hdr.keys()) and (hdr[1000005] is not None): return 1 return 0
def umount(self): pass
def setupTransaction(self, comps, dialog=None): # figure out what we're installing so that we can do a # dependency check l = [] toremove = [] upgradecount = 0 for pkg in comps.hdrlist.values(): if pkg.installState == TOINSTALL: l.append(pkg) elif pkg.installState == TOUPGRADE: l.append(pkg) # we need to have an extra counter for packages being # upgraded to handle the removal and the install callback's # effects on the progressbar upgradecount = upgradecount + 1 elif pkg.installState == TOREMOVE: toremove.append(pkg) # sort to cd order l.sort(install.sortPackages)
ts = rpm.TransactionSet("/") # FIXME: we should probably check signatures now... ts.setVSFlags(~(rpm.RPMVSF_NODSA|rpm.RPMVSF_NORSA)) # use anaconda ordering ts.setFlags(rpm.RPMTRANS_FLAG_ANACONDA)
# set up transaction set for p in l: if p['name'] in install_pkgs: ts.addInstall(p.hdr, p.hdr, "i") else: ts.addInstall(p.hdr, p.hdr, "u") for p in toremove: ts.addErase(p[rpm.RPMTAG_NAME])
depcheck = GroupSet.DependencyChecker(comps, "u")
dialog.prepare_block (1.0, _("Computing package dependencies")) unresolvable_dependencies = ts.check(depcheck.callback)
if unresolvable_dependencies != []: raise UnresolvableDependencies (unresolvable_dependencies)
# Now, we check to make sure that we aren't removing a package # we're not supposed to be removing. unremovable_list = [] black_list = self.getRemovalBlackList (comps)
for te in ts: if te.Type() != (1 << 1): # TR_REMOVED continue if str (te.N()) in black_list: unremovable_list.append ((te.N(), "")) if unremovable_list != []: raise DepsCheckComps ([], unremovable_list)
return ts def installPackages(self, ts, comps, dialog=None): # FIXME: handle the case for eg the docs cd where we really do want # to call ts.order(). ARGH :/
l = 0 for te in ts: l += 1
cb = install.InstallCallback(self, dialog, l, comps, ts) ts.setProbFilter(~rpm.RPMPROB_FILTER_DISKSPACE) try: problems = ts.run(cb.cb, 0) except install.InstallErrorException: rc = GenericError("error", _("Error installing packages"), _("There was an error installing packages.\n\n" "Exiting.")).display() del ts gtk.main_quit() sys.exit(1) if problems: GenericError("error", _("Not enough disk space"), formatProblems(problems)).display() else: for te in ts: if te.Type() == (1 << 1): # TR_REMOVED comps.hdrlist[GroupSet.tenevra(te)].installState = NOT_INSTALLED elif te.Type() == (1 << 0): # TR_ADDED comps.hdrlist[GroupSet.tenevra(te)].installState = INSTALLED else: log("unknown type %s for te %s" %(te.Type(), te.NEVR())) self.filesDone() del ts
# returns a list of packages that cannot be removed def getRemovalBlackList (self, comps): black_list = [] # sanity check that they have a sane system afterwards black_list.append ('redhat-config-packages') # removing scrollkeeper also removes a lot of things that are # "useful" -- unfortunately, this will make authoring and publishing # impossible to remove in 8.0 black_list.append('scrollkeeper') try: base = comps.groups['base'] except KeyError: # no comps. We'll have to trust redhat-config-packages is # good enough to keep the system sane. return black_list for package in base.packageInfo (type = PKGTYPE_MANDATORY): black_list.append (comps.hdrlist[package].nevra())
return black_list
class InstalledPackageMethod(InstallMethod): """Dummy method for already installed packages."""
def __init__(self): InstallMethod.__init__(self)
def getFilename(self, h, pkgTimer, installed = 0): raise RuntimeError, "Can't get filename of an already installed package"
class IndividualInstallMethod(InstallMethod): """Install method for installing individual packages
This is a fast-path without the real header list or anything else to try to make the install faster """ def __init__(self): InstallMethod.__init__(self)
def readCompsViaMethod(self, hdlist, update_method=None): return GroupSet.groupSetFromCompsFile(None, hdlist, doSelect = 0, update_method=update_method)
def readHeaders(self, update_method=None): return GroupSet.HeaderList([], self)
def getFilename(self, h, pkgTime, installed = 0): if h[RCPFILELOCATIONTAG] is not None: return h[RCPFILELOCATIONTAG] else: raise RuntimeError, "Individual package doesn't have filename defined"
def unlinkFilename(self, fn): pass
def filesDone(self): pass class LoopbackIsoInstallMethod(InstallMethod): """Install method for installing packages from loopback mounted CDs.""" def __init__(self, tree): InstallMethod.__init__(self) self.tree = tree self.discImages = findIsoImages(tree)
self.currentDisc = [] self.isMounted = 0 self.loopDev = None
# FIXME: need to get this from somewhere better self.mountpoint = get_fallback_mountpoint()
self.mountDisc(1) if not os.access(self.mountpoint + "/.discinfo", os.O_RDONLY): GenericError(TYPE_ERROR, _("Installation Tree Not Found."), _("The path %s does not look like a valid installation source.") % self.tree).display()
sys.exit(0)
discid = rhpl.discid.discid() discid.read(self.mountpoint + "/.discinfo")
self.releaseName = discid.release_name self.discidPixmapPath = "%s/%s" % (self.mountpoint, discid.pixmap_path) self.pixmapPath = [ "%s/%s" % (self.mountpoint, discid.pixmap_path), "/usr/share/pixmaps/comps", "/usr/share/pixmaps" ] self.baseDir = discid.comps_path self.packagesDir = discid.rpms_path self.timestamp = discid.timestamp
def getDiscs(self): # we have to have a disc mounted here if self.isMounted == 0: return [] if os.access(self.mountpoint + "/.discinfo", os.R_OK): discid = rhpl.discid.discid() discid.read(self.mountpoint + "/.discinfo") return getDiscNums(discid.disc_number) return []
def readCompsViaMethod(self, hdlist, update_method=None): self.mountDisc(1) return GroupSet.groupSetFromCompsFile("file://%s/%s/comps.xml" %(self.mountpoint, self.baseDir), hdlist, doSelect = 0, update_method=update_method)
def readHeaders(self, update_method=None): self.mountDisc(1) return GroupSet.HeaderListFromFile("%s/%s/hdlist" % (self.mountpoint, self.baseDir), self, update_method)
def mountDisc(self, discNum): if discNum in self.currentDisc and self.isMounted == 1: return self.umount() self.loopDev = diskutil.getUnusedLoop() diskutil.losetup(self.loopDev, self.tree + "/" + self.discImages[discNum], readOnly = 1) if not self.mount(self.loopDev, "iso9660", 1): self.currentDisc = self.getDiscs()
def mount(self, dev, fstype, readOnly = 1): if self.isMounted != 0: self.umount()
rc = diskutil.mount(dev, self.mountpoint, fstype, readOnly) if not rc: self.isMounted = 1 return rc
def umount(self): if self.isMounted == 0: return
diskutil.umount(self.mountpoint) if self.loopDev is not None: diskutil.unlosetup(self.loopDev) self.isMounted = 0 self.currentDisc = []
def getFilename(self, h, timer, installed=0): if h[RCPFILELOCATIONTAG] is not None: return h[RCPFILELOCATIONTAG]
if (1000002 not in h.hdr.keys()) or (h[1000002] is None): log("header for %s has no disc location tag, assuming it's " "on the current CD" % (h[1000000],)) elif h[1000002] not in self.currentDisc: self.mountDisc(h[1000002])
if not self.isUpdateRPM(h): path = self.packagesDir else: path = "%s/../Updates" %(self.packagesDir,) return "%s/%s/%s" %(self.mountpoint, path, h[1000000])
def unlinkFilename(self, fn): pass
def filesDone(self): if self.isMounted != 0: self.umount()
class CdromInstallMethod(InstallMethod): """Install method for installing packages from CDroms.""" def __init__(self, device = None, mountpoint = get_fallback_mountpoint(), alreadyMounted = 0): global currentCdDev global cdMntpt InstallMethod.__init__(self) currentCdDev = device cdMntpt = mountpoint
if alreadyMounted != 0: self.currentDisc = [ alreadyMounted ] self.isMounted = 1 else: self.currentDisc = [] self.isMounted = 0
self.cdlist = getCdDevs() # if we have more than one CD and the device is set to the default # go ahead and change our default device if len(self.cdlist) > 0 and currentCdDev is None: keys = self.cdlist.keys() keys.sort() currentCdDev = self.cdlist[keys[0]]
self.readDiscInfo()
def readDiscInfo(self): global currentCdDev global cdMntpt done = 0 if self.isMounted == 1: if os.access(cdMntpt + "/.discinfo", os.O_RDONLY): done = 1 while not done: for dev in self.cdlist.keys(): try: if self.mount(dev, fstype = "iso9660"): continue except: continue if os.access(cdMntpt + "/.discinfo", os.O_RDONLY): done = 1 break else: self.umount() if not done: dialog = CDDialog("", 1, None) retval = dialog.display() if (retval == gtk.RESPONSE_CANCEL or retval == gtk.RESPONSE_DELETE_EVENT): sys.exit (0) if not os.access(cdMntpt + "/.discinfo", os.O_RDONLY): GenericError(TYPE_ERROR, _("Installation Tree Not Found."), _("The path %s does not look like a valid installation source.") % currentCdDev).display() self.umount() sys.exit(0)
discid = rhpl.discid.discid() discid.read(cdMntpt + "/.discinfo") self.timestamp = discid.timestamp self.releaseName = discid.release_name
self.discidPixmapPath = "%s/%s" % (cdMntpt, discid.pixmap_path) self.pixmapPath = [ "%s/%s" %(cdMntpt, discid.pixmap_path), "/usr/share/pixmaps/comps", "/usr/share/pixmaps" ] self.baseDir = "%s/%s" % (cdMntpt, discid.comps_path) self.packagesDir = discid.rpms_path
self.currentDisc = getDiscNums(discid.disc_number)
if not os.access("%s/comps.xml" %(self.baseDir,), os.O_RDONLY): GenericError("error", _("Unable to find comps file."), _("The comps package does not appear to be " "installed. This package is required for " "the main package management interface of " "the package manager.")).display() self.umount() sys.exit(0)
def readCompsViaMethod(self, hdlist, update_method=None): return GroupSet.groupSetFromCompsFile("file://" + self.baseDir + "/comps.xml", hdlist, doSelect = 0, update_method=update_method)
def readHeaders(self, update_method=None): return GroupSet.HeaderListFromFile(self.baseDir + "/hdlist", self, update_method)
def getDiscs(self): global cdMntpt # we have to have a disc mounted here if self.isMounted == 0: return [] if os.access(cdMntpt + "/.discinfo", os.R_OK): discid = rhpl.discid.discid() discid.read(cdMntpt + "/.discinfo") return getDiscNums(discid.disc_number) return []
def mount(self, dev, fstype, readOnly = 1): global cdMntpt if self.isMounted != 0: print "something is mounted" self.umount()
try: rc = diskutil.mount(dev, self.cdlist[dev], fstype, readOnly) except Exception, e: print "exception while mounting: %s" %(e,) rc =1 if not rc: self.isMounted = 1 self.currentDisc = self.getDiscs() cdMntpt = self.cdlist[dev] else: f = open('/etc/mtab', 'r') lines = f.readlines() f.close() print "looking for me in /etc/mtab" print "dev is: %s, where is: %s" %(dev, self.cdlist[dev])
for line in lines: print line (mntdev, where, foo) = line.split(' ', 2) if mntdev == dev and where == self.cdlist[dev]: print "found it" self.isMounted = 1 self.currentDisc = self.getDiscs() cdMntpt = self.cdlist[dev] rc = 0 break return rc
def umount(self): global cdMntpt try: diskutil.umount(cdMntpt) except: pass self.isMounted = 0 self.currentDisc = []
def getFilename(self, h, timer, installed=0): global currentCdDev global cdMntpt if h[RCPFILELOCATIONTAG] is not None: return h[RCPFILELOCATIONTAG] if (1000002 not in h.hdr.keys()) or (h[1000002] is None): log("header for %s has no disc location tag, assuming it's " "on the current CD" % (h[1000000],)) elif h[1000002] not in self.currentDisc: needed = h[1000002] self.umount()
done = 0
for dev in self.cdlist.keys(): try: if not self.mount(dev, fstype = "iso9660"): if os.access(cdMntpt + "/.discinfo", os.O_RDONLY): f = open(cdMntpt + "/.discinfo") newStamp = f.readline().strip() try: descr = f.readline().strip() except: descr = None try: arch = f.readline().strip() except: arch = None try: discNum = getDiscNums(f.readline().strip()) except: discNum = [ 0 ] f.close() if (int(string.atof(newStamp)) == int(string.atof(self.timestamp)) and arch == getArch() and needed in discNum): self.currentDisc = discNum done = 1 currentCdDev = dev
if not done: self.umount() except: pass
if done: break
if not done: try: diskutil.ejectCdrom(currentCdDev) except: pass
while not done: dialog = CDDialog (self.getReleaseName(), needed, installed, None) retval = dialog.display () if retval == gtk.RESPONSE_CANCEL or retval == gtk.RESPONSE_DELETE_EVENT: sys.exit (0) found = 0 for dev in self.cdlist.keys(): print "trying to mount", dev try: if self.mount(dev, fstype = "iso9660"): time.sleep(3) if self.mount(dev, fstype = "iso9660"): continue print "mounted it" found = 1 if os.access(cdMntpt + "/.discinfo", os.O_RDONLY): f = open(cdMntpt + "/.discinfo") newStamp = f.readline().strip() try: descr = f.readline().strip() except: descr = None try: arch = f.readline().strip() except: arch = None try: discNum = getDiscNums(f.readline().strip()) except: discNum = [ 0 ] f.close() if (int(string.atof(newStamp)) == int(string.atof(self.timestamp)) and arch == getArch() and needed in discNum): done = 1 self.currentDisc = discNum currentCdDev = dev else: diskutil.umount(cdMntpt) except Exception, e: print "error mounting: ", e pass
if not found: # kind of a hack, but it works -- if we didn't ever # manage to mount anything, we should say that # the disk can't be accessed whereas if we managed # to mount something, they just inserted the wrong # CD GenericError(TYPE_ERROR, _("Unable to access disk."), _("The disk was unable to be accessed for reading. Please confirm that it is in the drive and try again.")).display() elif not done: ## GenericError(TYPE_ERROR, ## _("Incorrect disk found."), ## _("The wrong CD-ROM was inserted into the drive. Please check it and try again.")).display() try: diskutil.ejectCdrom(currentCdDev) except: pass # timer.start()
if not self.isUpdateRPM(h): path = self.packagesDir else: path = "%s/../Updates" %(self.packagesDir,) return "%s/%s/%s" % (cdMntpt, path, h[1000000])
def unlinkFilename(self, fn): pass
def filesDone(self): if self.isMounted != 0: self.umount()
class RedHatCdromInstallMethod(CdromInstallMethod): """Install method for installing packages from Red Hat Linux CDroms.""" def __init__(self, device = None, mountpoint = get_fallback_mountpoint(), alreadyMounted = 0): CdromInstallMethod.__init__(self, device, mountpoint, alreadyMounted)
def readDiscInfo(self): global currentCdDev self.discidPixmapPath = "/usr/share/pixmaps" self.pixmapPath = [ "/usr/share/pixmaps/comps", "/usr/share/pixmaps" ] self.baseDir = "/usr/share/comps/%s" % (getArch(),) self.packagesDir = "RedHat/RPMS" if not os.access(self.baseDir + "/.discinfo", os.O_RDONLY): GenericError(TYPE_ERROR, _("Installation Tree Not Found."), _("The path %s does not look like a valid installation source.") % currentCdDev).display() sys.exit(0)
discid = rhpl.discid.discid() discid.read(self.baseDir + "/.discinfo") self.timestamp = discid.timestamp self.releaseName = discid.release_name self.packagesDir = discid.rpms_path
if not os.access("%s/comps.xml" %(self.baseDir,), os.O_RDONLY): GenericError("error", _("Unable to find comps file."), _("The comps package does not appear to be " "installed. This package is required for " "the main package management interface of " "the package manager.")).display() sys.exit(0)
class TreeInstallMethod(InstallMethod): """Install method for installing from a tree.
This can be useful for both installing packages from an exploded Red Hat Linux tree and for installing from additional mounted CDs.""" def __init__(self, tree): InstallMethod.__init__(self) self.tree = tree
if not os.access(self.tree + "/.discinfo", os.O_RDONLY): GenericError(TYPE_ERROR, _("Installation Tree Not Found."), _("The path %s does not look like a valid installation source.") % self.tree).display() sys.exit(0)
discid = rhpl.discid.discid() discid.read(self.tree + "/.discinfo")
self.releaseName = discid.release_name self.discidPixmapPath = "%s/%s" % (self.tree, discid.pixmap_path) self.pixmapPath = [ "%s/%s" % (self.tree, discid.pixmap_path), "/usr/share/pixmaps/comps", "/usr/share/pixmaps" ] self.baseDir = discid.comps_path self.packagesDir = discid.rpms_path
def readCompsViaMethod(self, hdlist, update_method=None): return GroupSet.groupSetFromCompsFile("file://%s/%s/comps.xml" % (self.tree, self.baseDir), hdlist, doSelect = 0, update_method=update_method)
def readHeaders(self, update_method=None): return GroupSet.HeaderListFromFile("%s/%s/hdlist" % (self.tree, self.baseDir), self, update_method=None)
def getFilename(self, h, pkgTimer, installed=0): if h[RCPFILELOCATIONTAG] is not None: return h[RCPFILELOCATIONTAG]
if not self.isUpdateRPM(h): path = self.packagesDir else: path = "%s/../Updates" %(self.packagesDir,) return "%s/%s/%s" % (self.tree, path, h[1000000])
def unlinkFilename(self, fn): pass
def filesDone(self): pass
# FIXME: pulled straight from anaconda. could probably be made nicer def findIsoImages(path): files = os.listdir(path) arch = getArch() discImages = {}
# FIXME: this is kind of ugly, but we want to make sure we can mount mountpoint = get_fallback_mountpoint() origmnt = mountpoint i = 1 while not os.path.isdir(mountpoint): if not os.access(mountpoint, os.O_RDONLY): try: os.mkdir(mountpoint, 0755) continue except: pass mountpoint = "%s%d" %(origmnt, i) i = i + 1
if i > 10: raise RuntimeError, "Unable to create directory to mount CDs"
for file in files: what = path + '/' + file if os.path.isfile(what) and not fileIsIso(what): continue
loopDev = diskutil.getUnusedLoop() try: diskutil.losetup(loopDev, what, readOnly = 1) except SystemError: continue
try: diskutil.mount(loopDev, mountpoint, fstype = "iso9660", readOnly = 1) for num in range(1, 10): if os.access(mountpoint + "/.discinfo", os.R_OK): f = open(mountpoint + "/.discinfo") try: f.readline() # skip timestamp f.readline() # skip release description discArch = string.strip(f.readline()) # read architecture
# get the disc numbers for this disc numline = f.readline().strip() discNum = getDiscNums(numline) except: discArch = None discNum = [ 0 ]
f.close()
if num not in discNum or discArch != arch: continue # warn user if images appears to be wrong size if os.stat(what)[stat.ST_SIZE] % 2048: log("The ISO image %s has a size which is not " "a multiple of 2048 bytes. This may mean " "it was corrupted on transfer to this computer.") discImages[num] = file
diskutil.umount(mountpoint) except SystemError: pass
diskutil.unlosetup(loopDev)
return discImages
def fileIsIso(filename): fd = os.open(filename, os.O_RDONLY)
for blk in range(16, 100): if os.lseek(fd, blk * 2048 + 1, 0) < 0: os.close(fd) return 0
buf = os.read(fd, 5) if buf == "CD001": os.close(fd) return 1
os.close(fd) return 0
def getDiscNums(line): # get the disc numbers for this disc nums = line.split(",") discNums = [] for num in nums: discNums.append(int(num)) return discNums
# new dbus-python api as of dbus 0.33 def getDbusHalDevs(): global cdMntpt cddevs = {}
# get the devices from HAL bus = dbus.SystemBus() hal_manager = bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
drives = hal_manager.FindDeviceByCapability('storage.cdrom', dbus_interface='org.freedesktop.Hal.Manager') for d in drives: devobj = bus.get_object('org.freedesktop.Hal', d) deviface = dbus.Interface(devobj, 'org.freedesktop.Hal.Device') props = deviface.GetAllProperties() try: # we have to be able to get a lock on it to keep g-v-m from # mounting it from under us deviface.Lock("cd devs locked by system-config-packages") except Exception, e: print "Unable to get lock on device %s: %s" %(props["block.device"], e) continue dev = props["block.device"] while os.path.islink(dev): dev = os.readlink(dev) cddevs[dev] = cdMntpt
print "hal devs is", cddevs return cddevs
# this uses the dbus-python <= 0.32 api def getDbus032HalDevs(): global cdMntpt cddevs = {}
# get the devices from HAL bus = dbus.Bus (dbus.Bus.TYPE_SYSTEM) hal_service = bus.get_service ('org.freedesktop.Hal') hal_manager = hal_service.get_object ('/org/freedesktop/Hal/Manager', 'org.freedesktop.Hal.Manager')
drives = hal_manager.FindDeviceByCapability('storage.cdrom') for d in drives: devobj = hal_service.get_object(d, "org.freedesktop.Hal.Device") props = devobj.GetAllProperties() try: # we have to be able to get a lock on it to keep g-v-m from # mounting it from under us devobj.Lock("cd devs locked by system-config-packages") except Exception, e: print "Unable to get lock on device %s: %s" %(props["block.device"], e) continue dev = props["block.device"] while os.path.islink(dev): dev = os.readlink(dev) cddevs[dev] = cdMntpt
print "hal devs is", cddevs return cddevs
if not dbus.__dict__.has_key("version") or dbus.version < (0, 40, 0): getHalDevs = getDbus032HalDevs else: getHalDevs = getDbusHalDevs
def getKudzuDevs(): global cdMntpt cddevs = {}
drives = kudzu.probe(kudzu.CLASS_CDROM, kudzu.BUS_UNSPEC, kudzu.PROBE_ALL) for d in drives: dev = "/dev/%s" %(d.device,) while os.path.islink(dev): dev = os.readlink(dev) cddevs[dev] = cdMntpt
print "kudzudevs is", cddevs return cddevs
def getCdDevs(): cddevs = {} try: cddevs = getHalDevs() except Exception, e: print "error getting devices using HAL, falling back to kudzu: %s" %(e,) cddevs = getKudzuDevs()
f = open ('/etc/fstab', "r") lines = f.readlines () f.close()
# figure out where we want to mount the device for line in lines: fields = string.split (line)
if not fields: continue
if line[0] == "#": # skip all comments continue
# all valid fstab entries have 6 fields; if the last two are missing # they are assumed to be zero per fstab(5) if len(fields) < 4: continue elif len(fields) == 4: fields.append(0) fields.append(0) elif len(fields) == 5: fields.append(0) elif len(fields) > 6: continue
dev = fields[0] while os.path.islink(dev): dev = os.readlink(dev) if cddevs.has_key(dev): cddevs[dev] = fields[1]
return cddevs
|