fedora-updates-system/updatessystem Comet.py, 1.1, 1.2 admin.py, 1.1, 1.2 buildsys.py, 1.4, 1.5 controllers.py, 1.9, 1.10 mail.py, 1.2, 1.3 model.py, 1.7, 1.8 new.py, 1.7, 1.8 push.py, 1.3, 1.4

Luke Macken (lmacken) fedora-extras-commits at redhat.com
Sat Jan 6 08:03:23 UTC 2007


Author: lmacken

Update of /cvs/fedora/fedora-updates-system/updatessystem
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv8042/updatessystem

Modified Files:
	Comet.py admin.py buildsys.py controllers.py mail.py model.py 
	new.py push.py 
Log Message:
- lock down AdminController
- more identity integration
- create {pending,my} updates lists
- Allow push submissions
- Add F7 and EPEL5 releases
- Enable admin group
- Add beginning of PackageValidator and NewUpdateSchema
- Add AutoCompleteField to autocomplete package-version-release's in the new upd
ate form
- Other misc cleanups/fixes



Index: Comet.py
===================================================================
RCS file: /cvs/fedora/fedora-updates-system/updatessystem/Comet.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Comet.py	31 Dec 2006 09:10:14 -0000	1.1
+++ Comet.py	6 Jan 2007 08:03:21 -0000	1.2
@@ -14,9 +14,12 @@
    def __call__(self, func):
       def wrapper():
          for part in func():
-            yield ("--%(delim)s\r\n" + \
-                  "Content-type: %(type)s\r\n\r\n" + \
-                  "%(part)s" + \
-                  "--%(delim)s\r\n") % \
-                  {'delim':self.delim, 'part':str(part), 'type':self.type}
+            yield ("--%(delim)s\r\n" +
+                   "Content-type: %(type)s\r\n\r\n" +
+                   "%(part)s" +
+                   "--%(delim)s\r\n") % {
+                                           'delim' : self.delim,
+                                           'part':str(part),
+                                           'type':self.type
+                                        }
       return wrapper


Index: admin.py
===================================================================
RCS file: /cvs/fedora/fedora-updates-system/updatessystem/admin.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- admin.py	3 Jan 2007 21:21:17 -0000	1.1
+++ admin.py	6 Jan 2007 08:03:21 -0000	1.2
@@ -12,12 +12,20 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
-from turbogears import expose
+from push import PushController
+
+from turbogears import expose, identity
 from turbogears.identity import SecureResource
 from turbogears.controllers import Controller
+from turbogears.toolbox.catwalk import CatWalk
 
 class AdminController(Controller, SecureResource):
+    require = identity.in_group("admin")
+
+    push = PushController()
+    catwalk = CatWalk()
 
+   # @identity.require(identity.in_group('admin'))
     @expose(template='updatessystem.templates.admin')
     def index(self):
         return dict()


Index: buildsys.py
===================================================================
RCS file: /cvs/fedora/fedora-updates-system/updatessystem/buildsys.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- buildsys.py	31 Dec 2006 09:10:14 -0000	1.4
+++ buildsys.py	6 Jan 2007 08:03:21 -0000	1.5
@@ -30,11 +30,16 @@
 
     def get_source_path(self, update):
         """ Get the source path for a given package update """
+        pass
 
 class Brew(Buildsys):
     pass
 
 class Plague(Buildsys):
+    """
+    We want to talk to buildsys.fedoraproject.org and grab plague-results.
+    Some ideas have been to rsync the tree locally, or using FUSE sshfs.
+    """
     pass
 
 class LocalTest(Buildsys):


Index: controllers.py
===================================================================
RCS file: /cvs/fedora/fedora-updates-system/updatessystem/controllers.py,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- controllers.py	1 Jan 2007 06:16:13 -0000	1.9
+++ controllers.py	6 Jan 2007 08:03:21 -0000	1.10
@@ -18,21 +18,21 @@
 import cherrypy
 
 from new import NewUpdateController, update_form
-from push import PushController
 from admin import AdminController
 from model import Package, PackageUpdate, Release, Bugzilla, CVE
-from sqlite import IntegrityError
 from buildsys import SRPMNotFound
 from sqlobject import SQLObjectNotFound
 from turbogears import (controllers, expose, validate, redirect, identity,
                         paginate, flash, error_handler)
 
+from pysqlite2.dbapi2 import IntegrityError
+
 log = logging.getLogger(__name__)
 
 class Root(controllers.RootController):
 
     new = NewUpdateController()
-    push = PushController()
+    admin = AdminController()
 
     @expose()
     @identity.require(identity.not_anonymous())
@@ -68,13 +68,31 @@
         identity.current.logout()
         raise redirect("/")
 
+    @identity.require(identity.not_anonymous())
     @expose(template="updatessystem.templates.list")
     @paginate('updates', default_order='update_id', limit=15)
     def list(self):
         """ List all updates """
-        updates = PackageUpdate.select()
+        return dict(updates=PackageUpdate.select())
+
+    @identity.require(identity.not_anonymous())
+    @expose(template="updatessystem.templates.list")
+    @paginate('updates', default_order='update_id', limit=15)
+    def pending(self):
+        """ List all updates that are in a pending state """
+        updates = PackageUpdate.select(PackageUpdate.q.needs_push==True)
+        return dict(updates=updates)
+
+    @expose(template="updatessystem.templates.list")
+    @identity.require(identity.not_anonymous())
+    @paginate('updates', default_order='update_id', limit=15)
+    def mine(self):
+        """ List all updates submitted by the current user """
+        updates = PackageUpdate.select(PackageUpdate.q.submitter ==
+                                       identity.current.user_name)
         return dict(updates=updates)
 
+    @identity.require(identity.not_anonymous())
     @expose(template='updatessystem.templates.show')
     def show(self, update):
         try:
@@ -86,21 +104,34 @@
 
     @expose()
     @identity.require(identity.not_anonymous())
+    def submit(self, nvr):
+        """
+        Submit an update for pushing.
+        """
+        try:
+            up = PackageUpdate.byNvr(nvr)
+            up.needs_push = True
+            flash("%s has been submitted for pushing" % nvr)
+        except SQLObjectNotFound:
+            flash("Update %s not found" % nvr)
+        raise redirect('/show/%s' % nvr)
+
+    @expose()
+    @identity.require(identity.not_anonymous())
     def delete(self, update):
         try:
             up = PackageUpdate.byNvr(update)
         except SQLObjectNotFound:
             flash("Update %s not found" % update)
             raise redirect("/list")
+        log.debug("Deleting update %s" % up.nvr)
         if up.pushed:
-            # Removing pushed updates should essentially unpush
-            #           - remove from update stage (DONE)
-            #           - regenerate metadata (DONE)
-            #           - remove extended metadata TODO
-            #           - remove from database (DONE)
-            #           - sync to mirrors TODO
-            push.unpush_update(up)
-            push.generate_metadata(up)
+            log.info("Unpushing %s" % up.nvr)
+            for out in self.admin.push.unpush_update(up):
+                log.info(out)
+            for out in self.admin.push.generate_metadata(up):
+                log.info(out)
+            # TODO: remove extended metadata for this update
             up.destroySelf()
             mail.send_admin('deleted', up)
             flash("Deleted and unpushed %s" % update)
@@ -113,14 +144,13 @@
     @identity.require(identity.not_anonymous())
     @expose(template='updatessystem.templates.form')
     def edit(self, update):
-        import string
         try:
             up = PackageUpdate.byNvr(update)
         except SQLObjectNotFound:
             flash("Update %s not found")
             raise redirect("/list")
         values = {
-                'nvr'       : up.nvr,
+                'nvr'       : {'text': up.nvr, 'hidden' : up.nvr},
                 'release'   : up.release.name,
                 'testing'   : up.testing,
                 'type'      : up.type,
@@ -137,39 +167,50 @@
     @validate(form=update_form)
     @identity.require(identity.not_anonymous())
     def save(self, release, bugs, cves, edited, **kw):
-        """ Save an update.  This includes new updates and edited. """
-        release = Release.byName(release)
+        """
+        Save an update.  This includes new updates and edited.
+        Most of these checks should eventually make their way into the NewUpdateSchema
+        validators.
+        """
+        kw['nvr'] = kw['nvr']['text']
+
+        if not kw['nvr'] or kw['nvr'] == '':
+            flash("Please enter a package-version-release")
+            raise redirect('/new')
 
         if edited and kw['nvr'] != edited:
             flash("You cannot change the package n-v-r after submission")
             raise redirect('/edit/%s' % edited)
 
+        release = Release.select(Release.q.long_name == release)[0]
+
         if not edited: # new update
             try:
                 name = util.get_nvr(kw['nvr'])[0]
-                package = Package.byName(name)
+                try:
+                    package = Package.byName(name)
+                except SQLObjectNotFound:
+                    package = Package(name=name)
                 p = PackageUpdate(package=package, release=release,
-                                  submitter='FIXME', **kw)
-
-            # TODO: we should eventually put all of this stuff into a
-            # FancyValidator for the Package field
+                                  submitter=identity.current.user_name, **kw)
             except IndexError:
                 flash("Package needs to be in name-ver-rel format")
                 raise redirect('/new')
-            except SQLObjectNotFound:
-                flash("Package %s not found" % name)
-                raise redirect('/new')
-            except IntegrityError, e:
-                log.debug(e)
+            except IntegrityError:
                 flash("Update for %s already exists" % kw['nvr'])
                 raise redirect('/new')
             except SRPMNotFound:
                 flash("Cannot find SRPM for update")
                 raise redirect('/new')
-            log.debug("Adding new update %s" % package)
+            except Exception, e:
+                msg = "Unknown exception thrown: %s" % str(e)
+                log.error(msg)
+                flash(msg)
+                raise redirect('/new')
+            log.info("Adding new update %s" % kw['nvr'])
         else: # edited update
             from datetime import datetime
-            log.debug("Edited update %s" % edited)
+            log.info("Edited update %s" % edited)
             p = PackageUpdate.byNvr(edited)
             p.set(release=release, date_modified=datetime.now(), **kw)
             map(p.removeBugzilla, p.bugs)


Index: mail.py
===================================================================
RCS file: /cvs/fedora/fedora-updates-system/updatessystem/mail.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- mail.py	31 Dec 2006 09:10:14 -0000	1.2
+++ mail.py	6 Jan 2007 08:03:21 -0000	1.3
@@ -54,11 +54,11 @@
     'deleted' : {
         'subject' : '[Fedora Update] [deleted] %(package)s',
         'body'    : """\
-%(email)s has deleted the %(package)s update for %(release}s
+%(email)s has deleted the %(package)s update for %(release)s
 """,
         'fields'  : lambda x: {
-                        'email'     : x.submitter,
                         'package'   : x.nvr,
+                        'email'     : x.submitter,
                         'release'   : x.release.long_name
                     }
         },
@@ -92,11 +92,13 @@
 
 def send(to, msg_type, update):
     """ Send an update notification email to a given recipient """
-    message = turbomail.Message(from_addr,  to, messages[msg_type]['subject'] %
+    message = turbomail.Message(from_addr, to, messages[msg_type]['subject'] %
                                 {'package': update.nvr})
     message.plain = messages[msg_type]['body'] % \
                     messages[msg_type]['fields'](update)
-    turbomail.enqueue(message)
+    # TODO: uncomment me when we have the password situation figured out
+    # and can actually auth for outgoing mail
+    #turbomail.enqueue(message)
 
 def send_admin(msg_type, update):
     """ Send an update notification to the admins/release team. """


Index: model.py
===================================================================
RCS file: /cvs/fedora/fedora-updates-system/updatessystem/model.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- model.py	1 Jan 2007 06:16:13 -0000	1.7
+++ model.py	6 Jan 2007 08:03:21 -0000	1.8
@@ -18,7 +18,7 @@
 from sqlobject import *
 from datetime import datetime
 
-from turbogears import identity, config
+from turbogears import identity, config, flash
 from turbogears.database import PackageHub
 
 log = logging.getLogger(__name__)
@@ -29,7 +29,6 @@
     """ Table of releases that we will be pushing updates for """
     name        = UnicodeCol(alternateID=True, notNone=True)
     long_name   = UnicodeCol(notNone=True)
-    codename    = UnicodeCol()
     updates     = MultipleJoin('PackageUpdate', joinColumn='release_id')
     arches      = RelatedJoin('Arch')
     multilib    = RelatedJoin('Multilib')
@@ -84,15 +83,13 @@
     filelist        = PickleCol(default={}) # { 'arch' : [file1, file2, ..] }
 
     def _set_nvr(self, nvr):
-        """ Called when the a PackageUpdate is created. Here we do some 
-            initialization.
         """
-        from buildsys import SRPMNotFound
+        Called when the a PackageUpdate is created. Here we do some
+        initialization such as building the filelist
+        """
         self._SO_set_nvr(nvr)
-        try:
+        if self.filelist == {}:
             self._build_filelist()
-        except SRPMNotFound:
-            log.error("Unable to build filelist for %s" % nvr)
 
     def get_bugstring(self):
         import string
@@ -118,7 +115,7 @@
                 if isdir(path):
                     for file in os.listdir(path):
                         filelist[arch.name].append(join(path, file))
-                        print file
+                        log.debug(" * %s" % file)
             ## Check for multilib packages
             for compatarch in arch.compatarches:
                 path = join(sourcepath, compatarch)
@@ -157,9 +154,7 @@
     severity = UnicodeCol(default=None)
 
     _bz_server = config.get("bz_server")
-    _default_closemsg = config.get("bz_default_closemsg")
-    #_bz_server = 'https://bugzilla.redhat.com/bugzilla/xmlrpc.cgi'
-    #_default_closemsg = "%(package)s has been released for %(release)s.  If problems still persist, please make note of it in this bug report."
+    _default_closemsg = "%(package)s has been released for %(release)s.  If problems still persist, please make note of it in this bug report."
 
     def _set_bz_id(self, bz_id):
         self._SO_set_bz_id(bz_id)
@@ -169,7 +164,6 @@
         import xmlrpclib
         try:
             log.debug("Fetching bugzilla title for bug #%d" % self.bz_id)
-            log.debug("Using bugzilla server %s" % self._bz_server)
             server = xmlrpclib.Server(self._bz_server)
             #me = User.by_user_name('updatesys')
             #bug = server.bugzilla.getBugSimple(self.bz_id, me.email_address,
@@ -253,26 +247,15 @@
 
     user_name = UnicodeCol(length=16, alternateID=True,
                            alternateMethodName="by_user_name")
-    #email_address = UnicodeCol(length=255, alternateID=True,
-    #                           alternateMethodName="by_email_address")
-    #display_name = UnicodeCol(length=255)
-    #password = UnicodeCol(length=40)
+    groups = RelatedJoin("Group", intermediateTable="user_group",
+                         joinColumn="user_id", otherColumn="group_id")
+
     def _get_permissions(self):
         perms = set()
         for g in self.groups:
             perms = perms | set(g.permissions)
         return perms
 
-    #def _set_password(self, cleartext_password):
-    #    "Runs cleartext_password through the hash algorithm before saving."
-    #    hash = identity.encrypt_password(cleartext_password)
-    #    self._SO_set_password(hash)
-
-    #def set_password_raw(self, password):
-    #    "Saves the password as-is to the database."
-    #    self._SO_set_password(password)
-
-
 
 class Permission(SQLObject):
     permission_name = UnicodeCol(length=16, alternateID=True,
@@ -285,15 +268,22 @@
                          otherColumn="group_id")
 
 ##
-## Populate database with the release and packages
+## Initialize the package/release/multilib tables
 ##
 if __name__ == '__main__':
-    """
-        Initialize the database with our release values and maybe some sample
-        updates.
-    """
+    import os
+    import sys
     import turbogears
-    turbogears.update_config(configfile='dev.cfg',
+    from os.path import join, isdir, isfile
+    from turbogears import config
+    sys.path.append('/usr/share/createrepo')
+    import genpkgmetadata
+
+    configfile = 'dev.cfg'
+    if not isfile('dev.cfg'):
+        configfile = 'prod.cfg'
+
+    turbogears.update_config(configfile=configfile,
                              modulename='updatessystem.config')
 
     hub.begin()
@@ -309,6 +299,7 @@
     Multilib.createTable(ifNotExists=True)
     Group.createTable(ifNotExists=True)
 
+    # TODO: remove unecessary arches
     arches = {
             # arch        subarches
             'i386'      : ['i386', 'i486', 'i586', 'i686', 'athlon', 'noarch'],
@@ -330,15 +321,23 @@
 
     releases = (
         {
+            'name'      : 'F7',
+            'long_name' : 'Fedora 7 Universe',
+            'arches'    : map(Arch.byName, ('i386', 'x86_64', 'ppc'))
+        },
+        {
             'name'      : 'FC6',
             'long_name' : 'Fedora Core 6',
-            'codename'  : 'Zod',
             'arches'    : map(Arch.byName, ('i386', 'x86_64', 'ppc'))
         },
         {
             'name'      : 'FC5',
             'long_name' : 'Fedora Core 5',
-            'codename'  : 'Bordeaux',
+            'arches'    : map(Arch.byName, ('i386', 'x86_64', 'ppc'))
+        },
+        {
+            'name'      : 'EPEL5',
+            'long_name' : 'RHEL5 Enterprise Extras',
             'arches'    : map(Arch.byName, ('i386', 'x86_64', 'ppc'))
         }
     )
@@ -349,10 +348,11 @@
     print "\nInitializing Release table and multilib packages..."
     for release in releases:
         num_multilib = 0
-        rel = Release(name=release['name'], long_name=release['long_name'],
-                      codename=release['codename'])
+        rel = Release(name=release['name'], long_name=release['long_name'])
         map(rel.addArch, release['arches'])
         for arch in biarch.keys():
+            if not biarch[arch].has_key(release['name'][-1]):
+                continue
             for pkg in biarch[arch][release['name'][-1]]:
                 try:
                     multilib = Multilib.byPackage(pkg)
@@ -362,23 +362,11 @@
                 multilib.addRelease(rel)
                 multilib.addArch(Arch.byName(arch))
         print rel
-        print " - Added %d multilib packages for this %s" % (num_multilib,
-                                                             rel.name)
-
-    ## TODO: Add packages from pkgdb ?
-    print "\nAdding packages..."
-    pkg = Package(name='gaim')
-    print pkg
+        print " - Added %d multilib packages for %s" % (num_multilib, rel.name)
 
     ##
     ## Initialize the updates-stage
     ##
-    import os
-    import sys
-    from os.path import join, isdir
-    from turbogears import config
-    sys.path.append('/usr/share/createrepo')
-    import genpkgmetadata
 
     stage_dir = config.get('stage_dir')
     print "\nInitializing the staging directory"
@@ -400,7 +388,7 @@
     os.mkdir(join(stage_dir, 'testing'))
     for release in Release.select():
         for status in ('', 'testing'):
-            dir = join(stage_dir, status, release.name[-1])
+            dir = join(stage_dir, status, release.name)
             os.mkdir(dir)
             mkmetadatadir(join(dir, 'SRPMS'))
             for arch in release.arches:
@@ -410,7 +398,8 @@
     ##
     ## Create the admin group
     ##
-    #admin = Group(display_name='Administrators', group_name='admin')
-    #print "\nCreating admin group\n", admin 
+    print "\nCreating admin group"
+    admin = Group(display_name='Administrators', group_name='admin')
+    print admin
 
     hub.commit()


Index: new.py
===================================================================
RCS file: /cvs/fedora/fedora-updates-system/updatessystem/new.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- new.py	1 Jan 2007 06:16:13 -0000	1.7
+++ new.py	6 Jan 2007 08:03:21 -0000	1.8
@@ -12,45 +12,100 @@
 # 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
 import util
 import logging
+import formencode
+
+from os.path import join
 
 from model import Release, Package, PackageUpdate, Bugzilla, CVE
 from sqlobject import SQLObjectNotFound
 
 from turbogears import (expose, controllers, validate, validators, flash,
-                        error_handler, redirect, identity)
+                        error_handler, redirect, identity, config)
 
 from turbogears.widgets import (WidgetsList, TextField, SingleSelectField,
                                 CheckBox, TextArea, CalendarDateTimePicker,
-                                TableForm, HiddenField)
+                                TableForm, HiddenField, AutoCompleteField)
 
 log = logging.getLogger(__name__)
 
 update_types = ('security', 'bugfix', 'enhancement')
 
 def get_releases():
-    return [rel.name for rel in Release.select()]
+    return [rel.long_name for rel in Release.select()]
+
+class PackageValidator(validators.FancyValidator):
+    messages = {
+            'bad_name' : 'Invalid package name; must be in package-version-'
+                         'release format',
+            'dupe'     : 'Package update %(nvr)s already exists'
+    }
+
+    def _to_python(self, value, state):
+        return value.strip()
+
+    def validate_python(self, value, state):
+        """
+        Run basic QA checks on the provided package name
+        """
+        # Make sure the package is in name-version-release format
+        if len(value.split('-') < 3):
+            raise Invalid(self.message('bad_name'), value, state)
+
+
+#class NewUpdateSchema(formencode.Schema):
+    #nvr = PackageValidator()
+    #release = validators.OneOf(get_releases())
+    #testing = validators.Bool()
+    #type = validators.OneOf(update_types)
+    #embargo = validators.DateTimeConverter()
+    #bugs = validators.String()
+    #cves = validators.String()
+    #notes = validators.String()
+
+## TODO: get package schema/validation working
 
 class UpdateFields(WidgetsList):
-    nvr = TextField(label='Package', validator=validators.NotEmpty)
+    nvr = AutoCompleteField(label='Package', search_controller='/new/pkgsearch',
+                            search_param='name', result_name='pkgs')
     release = SingleSelectField(options=get_releases,
                                 validator=validators.OneOf(get_releases()))
     testing = CheckBox(validator=validators.Bool)
     type = SingleSelectField(options=update_types,
-                             validator=validators.OneOf(update_types),
-                             attrs={'onChange': 'newType()'})
-    embargo = CalendarDateTimePicker(validator=validators.DateTimeConverter)
-    bugs = TextField(validator=validators.String)
-    cves = TextField(validator=validators.String)
-    notes = TextArea(validator=validators.String)
+                             validator=validators.OneOf(update_types))
+    embargo = CalendarDateTimePicker(validator=validators.DateTimeConverter())
+    bugs = TextField(validator=validators.String())
+    cves = TextField(validator=validators.String())
+    notes = TextArea(validator=validators.String())
     edited = HiddenField(default=None)
 
 update_form = TableForm(fields=UpdateFields(), submit_text='Submit')
 
 class NewUpdateController(controllers.Controller):
 
+    build_dir = config.get('build_dir')
+
     @identity.require(identity.not_anonymous())
     @expose(template="updatessystem.templates.form")
     def index(self, *args, **kw):
+        self.packages = os.listdir(self.build_dir)
         return dict(form=update_form, values={}, action="/save")
+
+    @expose(format="json")
+    def pkgsearch(self, name):
+        """
+        Called automagically by the AutoCompleteWidget.
+        Search the build tree for a given package and return a list of
+        package-version-release's that are found
+        """
+        matches = []
+        for package in self.packages:
+            if package == name:
+                for version in os.listdir(join(self.build_dir, package)):
+                    for release in os.listdir(join(self.build_dir, package,
+                                                   version)):
+                        matches.append('-'.join((package, version, release)))
+        matches.reverse() # newer version-releases first
+        return dict(pkgs = matches)


Index: push.py
===================================================================
RCS file: /cvs/fedora/fedora-updates-system/updatessystem/push.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- push.py	31 Dec 2006 09:10:14 -0000	1.3
+++ push.py	6 Jan 2007 08:03:21 -0000	1.4
@@ -20,7 +20,8 @@
 from Comet import comet
 from model import PackageUpdate
 from buildsys import buildsys
-from turbogears import controllers, expose, flash, redirect, config
+from datetime import datetime
+from turbogears import controllers, expose, flash, redirect, config, identity
 
 from os.path import isfile, isdir, basename, join
 
@@ -65,7 +66,6 @@
             raise redirect("/push")
         if not isinstance(updates, list):
             updates = [updates]
-        #cherrypy.response.headers['Content-Type'] = 'text/plain' 
         log.debug("Setting updates in session: %s" % updates)
         cherrypy.session['topush'] = updates
         return dict()
@@ -80,7 +80,7 @@
         """
         @comet(content_type='text/plain')
         def _do_push():
-            yield "Starting push\n"
+            yield "Starting push on %s\n" % datetime.now()
             try:
                 self._lock_repo()
                 yield "Acquired lock for repository"
@@ -90,38 +90,45 @@
                 yield err
                 return
 
-            line = '=' * 120
+            line = '=' * 100
             for package in cherrypy.session['topush']:
                 update = PackageUpdate.byNvr(package)
-                yield "%s\nPushing %s\n%s" % (line, update.nvr, line)
                 try:
+                    yield "%s\nPushing %s\n%s" % (line, update.nvr, line)
                     for output in self.push_update(update):
-                        log.debug(output)
+                        log.info(output)
                         yield output
+                    yield "%s\nGenerating repository metadata\n%s" % (line, line)
                     for output in self.generate_metadata(update):
+                        log.info(output)
                         yield output
+                    update.needs_push = False
+                    update.pushed = True
                     yield "Sending notification to %s\n" % update.submitter
+                    mail.send(update.submitter, 'pushed', update)
                 except Exception, e:
                     log.error("Exception during push: %s" % e)
                     yield "ERROR: Exception thrown during push: %s" % e
-                # TODO: enable me when we have identities working
-                #mail.send(update.submitter, 'pushed', update)
-                update.needs_push = False
-                update.pushed = True
+
             self._unlock_repo()
-            yield "Pushing Complete!\n" + line
+            cherrypy.session['topush'] = []
+            yield "\nPushing Complete! <%s>\n" % datetime.now()
 
         return _do_push()
 
 
     def get_dest_path(self, update, arch):
-        """ Return the destination path for a given update """
+        """
+        Return the destination path for a given update
+        """
         return join(self.stage_dir, update.testing and 'testing' or '',
-                    update.release.name[-1], arch)
+                    update.release.name, arch)
 
     def push_update(self, update):
-        """ Go through update.filelist, and push to buildsys.get_dest_path. """
-        log.debug("Pushing update %s" % update.nvr)
+        """
+        Go through update.filelist, and push files to buildsys.get_dest_path.
+        """
+        log.debug("push_update")
         try:
             for arch in update.filelist.keys():
                 dest = self.get_dest_path(update, arch)
@@ -137,7 +144,7 @@
                     yield "Pushing %s" % (filename)
                     os.link(file, destfile)
         except Exception, e:
-            yield "Caught the following exception during push: %s" % e
+            yield "Caught the following exception during push: %s" % str(e)
             for msg in self.unpush_update(update):
                 yield msg
 
@@ -156,19 +163,27 @@
                     os.unlink(destfile)
 
     def generate_metadata(self, update):
-        """ Generate the repomd for all repos that this update effects """
+        """
+        Generate the repomd for all repos that this update effects
+        """
         for arch in update.filelist.keys():
             repo = self.get_dest_path(update, arch)
-            cache_dir = join(self.createrepo_cache, 'fc%s-%s-%s' %
-                             (update.release.name[-1], arch, update.testing and
-                              'testing' or 'final'))
-            yield "Generating metadata for %s" % repo
+            cache_dir = join(self.createrepo_cache, 'fc%s-%s' %
+                             (update.release.name[-1], arch))
+
+            if not isdir(cache_dir):
+                log.info("Creating createrepo cache directory: %s" % cache_dir)
+                os.makedirs(cache_dir)
+
+            yield repo
             genpkgmetadata.main(['--cachedir', str(cache_dir), '-p', '-q',
                                 str(repo)])
+
             debugrepo = join(repo, 'debug')
             if isdir(debugrepo):
                  genpkgmetadata.main(['--cachedir', str(cache_dir), '-p', '-q',
                                      str(debugrepo)])
+                 yield repo
 
 ## Allow us to return a generator for streamed responses
 cherrypy.config.update({'/push/push_updates':{'stream_response':True}})




More information about the scm-commits mailing list