diff --git a/bodhi/admin.py b/bodhi/admin.py
index db096dd..7d80d25 100644
--- a/bodhi/admin.py
+++ b/bodhi/admin.py
@@ -110,9 +110,14 @@ class AdminController(Controller, SecureResource):
else:
# Get a list of all updates with a request that aren't
# unapproved security updates, or for a locked release
- requests = filter(lambda update: not update.release.locked,
- PackageUpdate.select(
- PackageUpdate.q.request != None))
+ requests = PackageUpdate.select(PackageUpdate.q.request != None)
+
+ # Come F13+, bodhi will not have locked releases. It will
+ # implement the 'No Frozen Rawhide' proposal, and treat 'locked'
+ # releases as pending.
+ #requests = filter(lambda update: not update.release.locked,
+ # PackageUpdate.select(
+ # PackageUpdate.q.request != None))
for update in requests:
if update.type == 'security' and not update.approved:
continue
diff --git a/bodhi/controllers.py b/bodhi/controllers.py
index fa2e7e1..8af5184 100644
--- a/bodhi/controllers.py
+++ b/bodhi/controllers.py
@@ -831,6 +837,20 @@ class Root(controllers.RootController):
flash_log(str(e))
raise InvalidUpdateException(params)
+ # Politely discourage devs from pushing critpath straight to stable
+ if (update.request == 'stable' and update.critpath and
+ 'qa' not in identity.current.groups and
+ 'releng' not in identity.current.groups):
+ note.append("You're pushing a critical path package directly to "
+ "stable, which is strongly discouraged. Please "
+ "consider pushing to testing first!")
+ # Discourage devs from pushing directly to stable for pending releases
+ elif update.request == 'stable' and update.release.locked:
+ note.append("This update is bypassing updates-testing for a "
+ "pending release, which is strongly discouraged. "
+ "Please ensure that it is properly tested, or "
+ "consider pushing it to testing first.")
+
flash_log('. '.join(note))
if request_format() == 'json':
diff --git a/bodhi/masher.py b/bodhi/masher.py
index c890d92..6ae1ee6 100644
--- a/bodhi/masher.py
+++ b/bodhi/masher.py
@@ -351,6 +351,11 @@ class MashTask(Thread):
"""
for update in self.updates:
release = update.release
+
+ # [No Frozen Rawhide] Don't mash stable repos for pending releases
+ if update.request == 'stable' and release.locked:
+ continue
+
if self.resume:
self.repos.add(release.stable_repo)
self.repos.add(release.testing_repo)
@@ -380,6 +385,10 @@ class MashTask(Thread):
for update in self.updates:
if update.request == 'stable':
self.tag = update.release.stable_tag
+ # [No Frozen Rawhide] Move stable builds going to a pending
+ # release to the Release.dist-tag
+ if update.release.locked:
+ self.tag = update.release.dist_tag
elif update.request == 'testing':
self.tag = update.release.testing_tag
elif update.request == 'obsolete':
diff --git a/bodhi/model.py b/bodhi/model.py
index 819b571..3428379 100644
--- a/bodhi/model.py
+++ b/bodhi/model.py
@@ -50,9 +50,12 @@ class Release(SQLObject):
updates = MultipleJoin('PackageUpdate', joinColumn='release_id')
id_prefix = UnicodeCol(notNone=True)
dist_tag = UnicodeCol(notNone=True) # ie dist-fc7
- locked = BoolCol(default=False)
metrics = PickleCol(default=None) # {metric: {data}}
+ # [No Frozen Rawhide] We're going to re-use this column to flag 'pending'
+ # releases, since we'll no longer need to lock releases in this case.
+ locked = BoolCol(default=False)
+
def get_version(self):
regex = re.compile('\D+(\d+)$')
return int(regex.match(self.name).groups()[0])
@@ -404,6 +407,17 @@ class PackageUpdate(SQLObject):
flash_log('%s does not have a request to revoke' % self.title)
return
+ # [No Frozen Rawhide] Disable pushing critical path updates for
+ # pending releases directly to stable.
+ if action == 'stable' and self.release.locked and self.critpath:
+ if ('releng' in identity.current.groups or
+ 'qa' in identity.current.groups):
+ self.comment('Critical path update approved by %s' %
+ identity.current.user_name, author='bodhi')
+ else:
+ log.info('Forcing critical path update into testing')
+ action = 'testing'
+
self.request = action
self.pushed = False
#self.date_pushed = None
@@ -811,6 +827,17 @@ class PackageUpdate(SQLObject):
return None
return int(self.updateid.split('-')[-1])
+ @property
+ def critpath(self):
+ """ Return whether or not this update is in the critical path """
+ critical = False
+ critpath_pkgs = config.get('critpath').split()
+ for build in self.builds:
+ if build.package.name in critpath_pkgs:
+ critical = True
+ break
+ return critical
+
class Comment(SQLObject):
timestamp = DateTimeCol(default=datetime.utcnow)
diff --git a/bodhi/templates/show.kid b/bodhi/templates/show.kid
index ea01bef..e81518a 100644
--- a/bodhi/templates/show.kid
+++ b/bodhi/templates/show.kid
@@ -67,12 +67,32 @@ karma = " %d" % (tg.url('/static/images/k
Push to Testing
+
+
+
+ Push Critical Path update to Stable
+
+
+ Push to Stable
+
+
Push to Stable
@@ -95,13 +115,33 @@ karma = "
- Mark as Stable
-
-
+ Mark Critical Path update as Stable
+
+
+ Mark as Stable
+
+
+ Mark as Stable
+
+