extras-buildsys/utils/pushscript Comps.py,NONE,1.1

Michael Schwendt (mschwendt) fedora-extras-commits at redhat.com
Wed Nov 8 20:23:59 UTC 2006


Author: mschwendt

Update of /cvs/fedora/extras-buildsys/utils/pushscript
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv29439

Added Files:
	Comps.py 
Log Message:
add Comps.py module


--- NEW FILE Comps.py ---
#!/usr/bin/python -t
# -*- mode: Python; indent-tabs-mode: nil; -*-
#
# 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; either version 2 of the License, or
# (at your option) any later version.
#
# 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 errno, os, sys
import commands, shutil, tempfile

import Utils

def _fingerprint(filename):
    """return MD5 fingerprint of a file"""
    import md5
    m = md5.new()

    if os.path.isfile(filename):
        f = open(filename,'r')
        data = f.read()
        f.close()
        m.update(data)
    return m.hexdigest()


class CompsUpdater:

    def __init__(self,cfg):
        self.tmpdir = None
        self.cfg = cfg


    def _cleanup(self):
        if self.tmpdir:
            shutil.rmtree(self.tmpdir)
            self.tmpdir = None

    
    def _backup(self):
        # Back up some security relevant files of the working-copy.
        # throws: OSError, IOError
        self.tmpdir = tempfile.mkdtemp('','.tmp',os.getcwd())
        for sourcefile in self.cfg.comps_dangerousfiles:
            targetfile = os.path.join(self.tmpdir,sourcefile.replace('/','___'))
            if os.path.exists(sourcefile):
                shutil.copy2(sourcefile,targetfile)


    def _restoreBackup(self):
        # Restore backups.
        # throws: IOError
        for f in os.listdir(self.tmpdir):
            sourcefile = os.path.join(self.tmpdir,f)
            targetfile = f.replace('___','/')
            Utils.install_copy(sourcefile,targetfile,True)
    

    def Update(self):
        self.workdir = os.path.join(cfg.rundir,'comps')
        if not os.path.exists(self.workdir):
            print 'WARNING: %s missing! Manual setup needed.' % self.workdir
            return

        self.olddir= os.getcwd()
        try:
            os.chdir(self.workdir)
            self._backup()
            if self._update(self.cfg.comps_up_pass1):
                self._restoreBackup()
                if self._update(self.cfg.comps_up_pass2):
                    for dist in self.cfg.alldists:
                        self._install(dist)
        except IOError:
            os.chdir(self.olddir)
            self._cleanup()
        except OSError:
            os.chdir(self.olddir)
            self._cleanup()
        except KeyboardInterrupt:
            os.chdir(self.olddir)
            self._cleanup()
            raise
        os.chdir(self.olddir)
        self._cleanup()


    def _update(self,cmd):
        # Update working-copy.
        if cmd:
            (rc, rv) = commands.getstatusoutput(cmd)
            print rv
            if rc:
                print 'WARNING: comps update failed: %s' % cmd
                return False
        return True


    def _install(self,dist):
        # If a new comps file for this dist exists, make sure it's
        # well-formed. Else delete it and return.
        # throws: IOError, OSError
        compsnew = self.cfg.comps_map.get(dist,None)
        if not compsnew or not os.path.exists(compsnew):
            return
        compsvalid = 'comps.xml.valid'
        command = 'xmllint %s --output %s' % (compsnew,compsvalid)
        (rc, rv) = commands.getstatusoutput(command)
        if rc:
            print 'WARNING: malformed %s' % compsnew
            if os.path.exists(compsnew):
                os.remove(compsnew)
            return
        
        # Install new comps file only if fingerprint differs.
        # First repo gets a new copy, further repos a hardlink.
        oldfingerprint = None
        newfingerprint = _fingerprint(compsvalid)
        reporoot = os.path.join(self.cfg.treedir,dist)
        linkloc = None
        for arch in self.cfg.archdict[dist]:  # list of repo archs
            compstarget = os.path.join(reporoot,arch,'comps.xml')
            if not oldfingerprint:
                oldfingerprint = _fingerprint(compstarget)
            if os.path.exists(compstarget) and (oldfingerprint == newfingerprint):
                # This copy of comps.xml is the same, don't overwrite it,
                # but use it as link source.
                linkloc = compstarget
                return
            print '  Updating %s' % compstarget
            if os.path.exists(compstarget):
                os.remove(compstarget)
            if linkloc:
                Utils.install_link_or_copy(linkloc,compstarget)
            else:
                Utils.install_copy(compsvalid,compstarget)
                linkloc = compstarget
                os.remove(compsvalid)


def main(cfg):
    c = CompsUpdater(cfg)
    c.Update()
    

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print 'Usage: %s <project>\n' % os.path.basename(sys.argv[0])
        sys.exit(errno.EINVAL)

    cfg = Utils.load_config_module(sys.argv[1])

    Utils.signer_gid_check(cfg.signersgid)
    os.umask(cfg.signersumask)

    main(cfg)
    sys.exit(0)




More information about the fedora-extras-commits mailing list