MINI SHELL

Server : Apache/2.2.2 (Fedora)
System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686
User : apache ( 48)
PHP Version : 5.2.9
Disable Function : NONE
Directory :  /proc/self/root/usr/lib/python2.4/site-packages/pirut/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //proc/self/root/usr/lib/python2.4/site-packages/pirut/__init__.py
#!/usr/bin/python -tt
#
# Copyright 2005  Red Hat, Inc.
#
# Jeremy Katz <katzj@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

import os, sys, fcntl
import string
import time
import rpm
import urllib2

import gtk
import gtk.glade
import gtk.gdk as gdk
import gobject
import pango

from rhpl.translate import _, N_

import yum
import yum.plugins
import yum.Errors
from yum.logger import Logger
from yum.constants import *
import urlgrabber, urlgrabber.progress

import DetailsDialog
import GroupSelector
import PackageList
import Progress
from constants import *
from Errors import *

PirutDetailsDialog = DetailsDialog.PirutDetailsDialog
PirutTransactionProgress = Progress.PirutTransactionProgress
PirutProgress = Progress.PirutProgress
PirutProgressCallback = Progress.PirutProgressCallback
PirutPackageList = PackageList.PirutPackageList
PirutGroupSelector = GroupSelector.GroupSelector

# lame main loop runner... this should probably just be where we need it
def _runGtkMain(*args):
    while gtk.events_pending():
        gtk.main_iteration()


YUM_PID_FILE = '/var/run/yum.pid'

class GraphicalYumBase(yum.YumBase):
    # FIXME: this is pulled directly from yum/output.py just for debugging
    def listTransaction(self):
        """returns a string rep of the  transaction in an easy-to-read way."""
        
        self.tsInfo.makelists()
        if len(self.tsInfo) > 0:
            out = """
=============================================================================
 %-22s  %-9s  %-15s  %-16s  %-5s
=============================================================================
""" % ('Package', 'Arch', 'Version', 'Repository', 'Size')
        else:
            out = ""

        for (action, pkglist) in [('Installing', self.tsInfo.installed),
                            ('Updating', self.tsInfo.updated),
                            ('Removing', self.tsInfo.removed),
                            ('Installing for dependencies', self.tsInfo.depinstalled),
                            ('Updating for dependencies', self.tsInfo.depupdated),
                            ('Removing for dependencies', self.tsInfo.depremoved)]:
            if pkglist:
                totalmsg = "%s:\n" % action
            for txmbr in pkglist:
                (n,a,e,v,r) = txmbr.pkgtup
                evr = txmbr.po.printVer()
                repoid = txmbr.repoid
                pkgsize = float(txmbr.po.size())
                size = pkgsize
                msg = " %-22s  %-9s  %-15s  %-16s  %5s\n" % (n, a,
                              evr, repoid, size)
                for (obspo, relationship) in txmbr.relatedto:
                    if relationship == 'obsoletes':
                        appended = '     replacing  %s.%s %s\n\n' % (obspo.name, obspo.arch, obspo.printVer())
                        msg = msg+appended
                totalmsg = totalmsg + msg
        
            if pkglist:
                out = out + totalmsg

        summary = """
Transaction Summary
=============================================================================
Install  %5.5s Package(s)         
Update   %5.5s Package(s)         
Remove   %5.5s Package(s)         
""" % (len(self.tsInfo.installed + self.tsInfo.depinstalled),
       len(self.tsInfo.updated + self.tsInfo.depupdated),
       len(self.tsInfo.removed + self.tsInfo.depremoved))
        out = out + summary
        
        return out

    
    def __init__(self, run_long = True, configfn = "/etc/yum.conf"):
        """run_long is whether or not to run 'long' steps."""
        
        self.logfile = None
        yum.YumBase.__init__(self)
        try:
            self.doConfigSetup(configfn)
        except yum.Errors.ConfigError, e:
            raise PirutError, e
        self.doPluginSetup(types=(yum.plugins.TYPE_CORE,))
        self.closeRpmDB()
        self.doTsSetup()

        self.unsignedok = False

        if run_long:
            self.reposSetup()

    def reposSetup(self, callback = None):
        if callback:
            self.repos.callback = callback
            callback.num_tasks += 10

        self.doLock(YUM_PID_FILE)

        self.doRpmDBSetup()
        if callback: callback.next_task()
        try:
            self.doRepoSetup()
        except yum.Errors.RepoError, e:
            raise PirutDownloadError, e
        if callback: callback.next_task()        
        try:
            self.doGroupSetup()
        except yum.Errors.GroupsError:
            self.errorlog(1, "no groups present!")
        if callback: callback.next_task(next = 5) # hack... next should be long
        self.doSackSetup()
        if callback: callback.next_task(incr=3)        

        if callback: self.repos.callback = None        

    def errorlog(self, level, msg):
        _runGtkMain()
        if level <= 0:
            print >> sys.stderr, "ERROR:", msg
        else:
            print >> sys.stderr, "WARNING:", msg

    def log(self, level, msg):
        _runGtkMain()
        if level <= 0:
            print >> sys.stderr, "LOG:", msg

    def filelog(self, level, msg):
        _runGtkMain()
        if self.logfile:
            self.logfile(level, msg)

    def simpleDBInstalled(self, name):
        # FIXME: doing this directly instead of using self.rpmdb.installed()
        # speeds things up by 400%
        mi = self.ts.ts.dbMatch('name', name)
        if mi.count() > 0:
            return True
        return False

    def isPackageInstalled(self, name = None, epoch = None, version = None,
                           release = None, arch = None, po = None):
        # FIXME: this sucks.  we should probably suck it into yum proper
        # but it'll need a bit of cleanup first.
        if po is not None:
            (name, epoch, version, release, arch) = po.returnNevraTuple()
            
        installed = False
        if name and not (epoch or version or release or arch):
            installed = self.simpleDBInstalled(name)
        elif self.rpmdb.installed(name = name, epoch = epoch, ver = version,
                                rel = release, arch = arch):
            installed = True
            
        lst = self.tsInfo.matchNaevr(name = name, epoch = epoch,
                                     ver = version, rel = release,
                                     arch = arch)
        for txmbr in lst:
            if txmbr.output_state in TS_INSTALL_STATES:
                return True
        if installed and len(lst) > 0:
            # if we get here, then it was installed, but it's in the tsInfo
            # for an erase or obsoleted --> not going to be installed at end
            return False
        return installed

    def isGroupInstalled(self, grp):
        if grp.selected:
            return True
        elif grp.installed and not grp.toremove:
            return True
        return False

    def deselectGroup(self, grpid):
        group = self.comps.return_group(grpid)
        if group.selected:
            yum.YumBase.deselectGroup(self, grpid)
        else:
            self.groupRemove(grpid)

    def selectGroup(self, grpid):
        group = self.comps.return_group(grpid)
        if group.toremove:
            self.groupUnremove(grpid)
        else:
            yum.YumBase.selectGroup(self, grpid)

    def _getKeyForPackage(self, po, mainwin = None):
        # FIXME: this should be in yum.  it's basically straight out of
        # yum/cli.py.  the userconfirm stuff is a little silly, though
        repo = self.repos.getRepo(po.repoid)
        keyurls = repo.gpgkey
        key_installed = False

        for keyurl in keyurls:
            self.log(1, 'Retrieving GPG key from %s' % keyurl)

            # Go get the GPG key from the given URL
            try:
                rawkey = urlgrabber.urlread(keyurl, limit=9999)
            except urlgrabber.grabber.URLGrabError, e:
                raise yum.Errors.YumBaseError('GPG key retrieval failed: ' +
                                              str(e))

            # Parse the key
            try:
                keyinfo = yum.misc.getgpgkeyinfo(rawkey)
                keyid = keyinfo['keyid']
                hexkeyid = yum.misc.keyIdToRPMVer(keyid).upper()
                timestamp = keyinfo['timestamp']
                userid = keyinfo['userid']
            except ValueError, e:
                raise yum.Errors.YumBaseError, \
                      'GPG key parsing failed: ' + str(e)

            # Check if key is already installed
            if yum.misc.keyInstalled(self.read_ts, keyid, timestamp) >= 0:
                self.errorlog(1, 'GPG key at %s (0x%s) is already installed' % (
                    keyurl, hexkeyid))
                continue

            # Try installing/updating GPG key
            self.log(1, 'Importing GPG key 0x%s "%s"' % (hexkeyid, userid))
            if hasattr(self.conf, "getConfigOption"):
                opt = self.conf.getConfigOption('assumeyes')
            else:
                opt = self.conf.assumeyes
            if not opt:
                d = gtk.MessageDialog(mainwin, gtk.DIALOG_MODAL,
                                      gtk.MESSAGE_QUESTION,
                                      message_format = _("Import key?"))
                sec = gobject.markup_escape_text(
                    _("The package %s is signed with a key "
                      "from %s (0x%s).  Would you like to "
                      "import this key?") %(po, userid, hexkeyid))
                d.format_secondary_text(sec)
                b = d.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
                b = d.add_button(_("_Import key"), gtk.RESPONSE_OK)
                b.set_image(gtk.image_new_from_stock(gtk.STOCK_OK,
                                                     gtk.ICON_SIZE_BUTTON))
                rc = d.run()
                d.destroy()
                
                if rc != gtk.RESPONSE_OK:
                    raise yum.Errors.YumBaseError, "Not installing key"
            
            # Import the key
            result = self.ts.pgpImportPubkey(yum.misc.procgpgkey(rawkey))
            if result != 0:
                raise yum.Errors.YumBaseError, \
                      'Key import failed (code %d)' % result
            self.log(1, 'Key imported successfully')
            key_installed = True

            if not key_installed:
                raise yum.Errors.YumBaseError, \
                      'The GPG keys listed for the "%s" repository are ' \
                      'already installed but they are not correct for this ' \
                      'package.\n' \
                      'Check that the correct key URLs are configured for ' \
                      'this repository.' % (repo.name)

            # Check if the newly installed keys helped
            result, errmsg = self.sigCheckPkg(po)
            if result != 0:
                self.log(0, "Import of key(s) didn't help, wrong key(s)?")
                raise yum.Errors.YumBaseError, errmsg

    def downloadPackages(self, mainwin):
        class dlcb(urlgrabber.progress.BaseMeter):
            def __init__(self, pbar, dlpkgs):
                urlgrabber.progress.BaseMeter.__init__(self)
                self.pbar = pbar
                self.total = float(len(dlpkgs))
                self.current = 0
                self.last = 0

            def _do_start(self, now):
                txt = _("Downloading %s") %(urllib2.unquote(self.basename),)
                self.pbar.set_markup("<i>%s</i>" %(txt,))

            def _do_end(self, amount_read, now=None):
                self.current += 1
                self.pbar.set_fraction(self.current / self.total)

            def update(self, amount_read, now=None):
                urlgrabber.progress.BaseMeter.update(self, amount_read, now)
                
            def _do_update(self, amount_read, now=None):
                if self.size is None:
                    return
                pct = float(amount_read) / self.size
                curval = self.pbar.get_fraction()
                newval = (pct * 1/self.total) + (self.current / self.total)
                if newval > curval + 0.001 or time.time() > self.last + 1:
                    self.pbar.set_fraction(newval)
                    _runGtkMain()
                    self.last = time.time()

        def downloadErrorDialog(mainwin, secondary, details = None):
            d = PirutDetailsDialog(mainwin, gtk.MESSAGE_ERROR,
                                   [('gtk-ok', gtk.RESPONSE_OK)],
                                   _("Error downloading packages"),
                                   secondary)
            if details:
                d.set_details("%s" %(details,))
            d.run()
            d.destroy()
            raise PirutDownloadError


        dlpkgs = map(lambda x: x.po, filter(lambda txmbr:
                                            txmbr.ts_state in ("i", "u"),
                                            self.tsInfo.getMembers()))
        
        pbar = PirutProgress(_("Downloading packages"), mainwin)
        dlCb = dlcb(pbar, dlpkgs)
        self.repos.setProgressBar(dlCb)
        pbar.show()
        try:
            probs = self.downloadPkgs(dlpkgs)
        except yum.Errors.RepoError, errmsg:
            downloadErrorDialog(mainwin, secondary = None, details = errmsg)
        except IndexError:
            downloadErrorDialog(mainwin, _("Unable to find a suitable mirror."))
            
        self.repos.setProgressBar(None)
        pbar.destroy()

        if len(probs.keys()) > 0:
            errstr = []
            for key in probs.keys():
                errors = yum.misc.unique(probs[key])
                for error in errors:
                    errstr.append("%s: %s" %(key, error))

            downloadErrorDialog(mainwin, _("Errors were encountered while "
                                           "downloading packages."),
                                details = string.join(errstr, "\n"))
            
        return dlpkgs

    def checkDeps(self, mainwin):
        class dscb:
            def __init__(self, pbar, ayum):
                self.log = ayum.log
                self.errorlog = ayum.errorlog
                self.pbar = pbar

                # if we run pending events when we get a callback, things
                # seem more responsive which is good (tm)
                self.pkgAdded = self.procReq = self.transactionPopulation = self.downloadHeader = self.tscheck = self.start = self.unresolved = self.procConflict = _runGtkMain

            def restartLoop(self):
                cur = self.pbar.get_fraction()
                new = ((1.0 - cur) / 2) + cur
                self.pbar.set_fraction(new)
                _runGtkMain()

            def end(self):
                self.pbar.set_fraction(1.0)
                _runGtkMain()

        pbar = PirutProgress(_("Resolving dependencies for updates"), mainwin)
        dsCB = dscb(pbar, self)
        self.dsCallback = dsCB
        pbar.show()
        try:
            (result, msgs) = self.buildTransaction()
        except yum.Errors.RepoError, errmsg:
            self.dsCallback = None # we only wanted this here.  blah.
            pbar.destroy()
            
            d = PirutDetailsDialog(mainwin, gtk.MESSAGE_ERROR,
                                          [('gtk-ok', gtk.RESPONSE_OK)],
                                          _("Error downloading headers"),
                                          _("Errors were encountered while "
                                            "downloading package headers."))
            d.set_details("%s" %(errmsg,))
            d.run()
            d.destroy()
            raise PirutDownloadError
        
        self.dsCallback = None # we only wanted this here.  blah.
        pbar.destroy()

        if result == 1:
            d = PirutDetailsDialog(mainwin, gtk.MESSAGE_ERROR,
                                 [('gtk-ok', gtk.RESPONSE_OK)],
                                 _("Error resolving dependencies"),
                                 _("Unable to resolve dependencies for some "
                                   "packages selected for installation."))
            d.set_details(string.join(msgs, "\n"))
            d.run()
            d.destroy()
            raise PirutDependencyError

    def depDetails(self, mainwin):
        self.tsInfo.makelists()
        if (len(self.tsInfo.depinstalled) > 0 or 
            len(self.tsInfo.depupdated) > 0 or
            len(self.tsInfo.depremoved) > 0):
            d = PirutDetailsDialog(mainwin, gtk.MESSAGE_INFO,
                                 [('gtk-cancel', gtk.RESPONSE_CANCEL),
                                  (_("Continue"), gtk.RESPONSE_OK, 'gtk-ok')],
                                 _("Dependencies added"),
                                 _("Updating these packages requires "
                                   "additional updates for proper "
                                   "operation."))

            b = gtk.TextBuffer()
            tag = b.create_tag('bold')
            tag.set_property('weight', pango.WEIGHT_BOLD)
            tag = b.create_tag('indented')
            tag.set_property('left-margin', 10)
            types=[(self.tsInfo.depinstalled,_("Adding for dependencies:\n")),
                   (self.tsInfo.depremoved, _("Removing for dependencies:\n")),
                   (self.tsInfo.depupdated, _("Updating for dependencies:\n"))]
            for (lst, strng) in types:
                if len(lst) > 0:
                    i = b.get_end_iter()
                    b.insert_with_tags_by_name(i, strng, "bold")
                    for txmbr in lst:
                        i = b.get_end_iter()
                        (n,a,e,v,r) = txmbr.pkgtup
                        b.insert_with_tags_by_name(i, "%s-%s-%s\n" % (n,v,r),
                                                   "indented")
            d.set_details(buffer = b)
            rc = d.run(timeout=20)
            d.destroy()
            if rc != gtk.RESPONSE_OK:
                raise PirutError

    def checkSignatures(self, pkgs, mainwin):
        pbar = PirutProgress(_("Verifying packages"), mainwin)
        num = float(len(pkgs))
        i = 1
        for po in pkgs:
            result, errmsg = self.sigCheckPkg(po)
            pbar.set_fraction(i / num)
            i+=1

            if result == 0:
                continue
            elif result == 1:
                found = True
                try:
                    self._getKeyForPackage(po, mainwin)
                except yum.Errors.YumBaseError, errmsg:
                    found = False
                if found:
                    continue

            # if we got here, either it failed to verify originally or failed
            # when we attempted to do an automagic import

            d = PirutDetailsDialog(mainwin, gtk.MESSAGE_ERROR,
                                   text = _("Unable to verify %s") %(po,))
            d.set_details("%s" %(errmsg,))

            if not self.unsignedok:
                pbar.destroy()
                d.add_button(_("_Close"), gtk.RESPONSE_CLOSE, 'gtk-close')
            else:
                d.format_secondary_markup(_("Malicious software can damage "
                                            "your computer or cause other "
                                            "harm.  Are you sure you wish "
                                            "to install this package?"))
                b = d.add_button(_("_Cancel"), gtk.RESPONSE_CANCEL,
                                 'gtk-cancel')
                b = d.add_button(_("_Install anyway"), gtk.RESPONSE_OK,
                                 'gtk-ok')
                d.set_default_response(gtk.RESPONSE_CANCEL)
            rc = d.run()
            d.destroy()
            if rc != gtk.RESPONSE_OK:
                raise PirutVerifyError
            
        pbar.destroy()

    def runTransaction(self, mainwin):
        def transactionErrors(errs):
            d = PirutDetailsDialog(mainwin, gtk.MESSAGE_ERROR,
                                          buttons = [('gtk-ok', 0)],
                                          text = _("Error updating software"))
            d.format_secondary_text(_("There were errors encountered in "
                                      "trying to update the software "
                                      "you selected"))
            d.set_details("%s" %(errs,))
            d.run()
            d.destroy()

        # FIXME: it's not always updating...
        pbar = PirutProgress(_("Updating software"), mainwin)
        tsprog = PirutTransactionProgress(pbar)

        del self.ts
        self.initActionTs() # make a new, blank ts to populate
        self.populateTs(keepold=0)
        self.ts.check() #required for ordering
        self.ts.order() # order

        tsprog.filelog = self.filelog
        tsprog.tsInfo = self.tsInfo

        pbar.show()
        try:
            tserrors = yum.YumBase.runTransaction(self, tsprog)
        except yum.Errors.YumBaseError, err:
            # FIXME: these errors are actually pretty bad and should be
            # formatted better
            pbar.destroy()
            transactionErrors(err)
            raise PirutError
                                 
        pbar.destroy()

    def setupLogging(self, logfn = None):
        # FIXME: this is all from yum/{cli,output}.py
        def printtime():
            months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                      'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
            now = time.localtime(time.time())
            ret = months[int(time.strftime('%m', now)) - 1] + \
                  time.strftime(' %d %T ', now)
            return ret

        if logfn is None:
            logfn = self.conf.logfile
        logpath = os.path.dirname(logfn)
        if not os.path.exists(logpath):
            try:
                os.makedirs(logpath, mode=0755)
            except OSError, e:
                self.errorlog(0, _('Cannot make directory for logfile %s' % logpath))
                sys.exit(1)
                
        try:
            logfd = os.open(logfn, os.O_WRONLY |
                            os.O_APPEND | os.O_CREAT, 0644)
        except OSError, e:
            self.errorlog(0, _('Cannot open logfile %s' % logfn))
            sys.exit(1)

        logfile =  os.fdopen(logfd, 'a')
        fcntl.fcntl(logfd, fcntl.F_SETFD)
        self.logfile = Logger(threshold = 10, file_object = logfile,
                              preprefix = printtime)

    def applyChanges(self, mainwin):
        """Apply all of the packaging changes requested."""
        # do depsolve.  determine if we've added anything or not.
        self.checkDeps(mainwin)
        self.depDetails(mainwin)

        # download and verify packages
        dlpkgs = self.downloadPackages(mainwin)
        self.checkSignatures(dlpkgs, mainwin)

        # run transaction
        self.runTransaction(mainwin)

    def quit(self, *args):
        # FIXME: should make sure we close down access to lock files and dbs
        # cleanly here
        try:
            self.closeRpmDB()
        except Exception, e:
            print >> sys.stderr, "Error closing rpmdb: ", e

        self.doUnlock(YUM_PID_FILE)
        try:
            gtk.main_quit()
        except:
            pass
        sys.exit(0)

def startupError(err):
    d = PirutDetailsDialog(None, gtk.MESSAGE_ERROR,
                           [(_("Exit"), gtk.RESPONSE_OK, 'gtk-quit')],
                           _("Config error."),
                           _("Unable to start due to a configuration "
                             "error."))
    d.set_details(str(err))
    d.run()
    d.destroy()
    sys.exit(2)    

Anon7 - 2021