changeset 3522:7174ee850baa beta

configurable locking codes. - this allows changing the default 423 LOCKED code to 2XX codes which don't break the transactions. Insted it gives users a warning for push.
author Marcin Kuzminski <marcin@python-works.com>
date Sun, 10 Mar 2013 22:53:25 +0100
parents cebc46122483
children e08321d4c106 6e8027c2f49c
files development.ini production.ini rhodecode/config/deployment.ini_tmpl rhodecode/lib/exceptions.py rhodecode/lib/hooks.py rhodecode/lib/middleware/simplegit.py rhodecode/lib/middleware/simplehg.py
diffstat 7 files changed, 59 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/development.ini	Sun Mar 10 21:24:11 2013 +0100
+++ b/development.ini	Sun Mar 10 22:53:25 2013 +0100
@@ -156,6 +156,11 @@
 ## handling that. Set this variable to 403 to return HTTPForbidden
 auth_ret_code =
 
+## locking return code. When repository is locked return this HTTP code. 2XX
+## codes don't break the transactions while 4XX codes do
+lock_ret_code = 423
+
+
 ####################################
 ###        CELERY CONFIG        ####
 ####################################
--- a/production.ini	Sun Mar 10 21:24:11 2013 +0100
+++ b/production.ini	Sun Mar 10 22:53:25 2013 +0100
@@ -156,6 +156,11 @@
 ## handling that. Set this variable to 403 to return HTTPForbidden
 auth_ret_code =
 
+## locking return code. When repository is locked return this HTTP code. 2XX
+## codes don't break the transactions while 4XX codes do
+lock_ret_code = 423
+
+
 ####################################
 ###        CELERY CONFIG        ####
 ####################################
--- a/rhodecode/config/deployment.ini_tmpl	Sun Mar 10 21:24:11 2013 +0100
+++ b/rhodecode/config/deployment.ini_tmpl	Sun Mar 10 22:53:25 2013 +0100
@@ -156,6 +156,11 @@
 ## handling that. Set this variable to 403 to return HTTPForbidden
 auth_ret_code =
 
+## locking return code. When repository is locked return this HTTP code. 2XX
+## codes don't break the transactions while 4XX codes do
+lock_ret_code = 423
+
+
 ####################################
 ###        CELERY CONFIG        ####
 ####################################
--- a/rhodecode/lib/exceptions.py	Sun Mar 10 21:24:11 2013 +0100
+++ b/rhodecode/lib/exceptions.py	Sun Mar 10 22:53:25 2013 +0100
@@ -60,12 +60,17 @@
 
 class HTTPLockedRC(HTTPClientError):
     """
-    Special Exception For locked Repos in RhodeCode
+    Special Exception For locked Repos in RhodeCode, the return code can
+    be overwritten by _code keyword argument passed into constructors
     """
     code = 423
     title = explanation = 'Repository Locked'
 
     def __init__(self, reponame, username, *args, **kwargs):
+        from rhodecode import CONFIG
+        from rhodecode.lib.utils2 import safe_int
+        _code = CONFIG.get('lock_ret_code')
+        self.code = safe_int(_code, self.code)
         self.title = self.explanation = ('Repository `%s` locked by '
                                          'user `%s`' % (reponame, username))
         super(HTTPLockedRC, self).__init__(*args, **kwargs)
--- a/rhodecode/lib/hooks.py	Sun Mar 10 21:24:11 2013 +0100
+++ b/rhodecode/lib/hooks.py	Sun Mar 10 22:53:25 2013 +0100
@@ -36,7 +36,7 @@
 from rhodecode.lib.vcs.backends.base import EmptyChangeset
 from rhodecode.lib.compat import json
 from rhodecode.lib.exceptions import HTTPLockedRC
-from rhodecode.lib.utils2 import safe_str, datetime_to_time
+from rhodecode.lib.utils2 import safe_str
 from rhodecode.model.db import Repository, User
 
 
@@ -113,7 +113,14 @@
     usr = User.get_by_username(username)
     if locked_by[0] and usr.user_id != int(locked_by[0]):
         locked_by = User.get(locked_by[0]).username
-        raise HTTPLockedRC(repository, locked_by)
+        # this exception is interpreted in git/hg middlewares and based
+        # on that proper return code is server to client
+        _http_ret = HTTPLockedRC(repository, locked_by)
+        if str(_http_ret.code).startswith('2'):
+            #2xx Codes don't raise exceptions
+            sys.stdout.write(_http_ret.title)
+        else:
+            raise _http_ret
 
 
 def pre_pull(ui, repo, **kwargs):
@@ -139,7 +146,14 @@
 
     if locked_by[0]:
         locked_by = User.get(locked_by[0]).username
-        raise HTTPLockedRC(repository, locked_by)
+        # this exception is interpreted in git/hg middlewares and based
+        # on that proper return code is server to client
+        _http_ret = HTTPLockedRC(repository, locked_by)
+        if str(_http_ret.code).startswith('2'):
+            #2xx Codes don't raise exceptions
+            sys.stdout.write(_http_ret.title)
+        else:
+            raise _http_ret
 
 
 def log_pull_action(ui, repo, **kwargs):
@@ -159,12 +173,14 @@
         repository = extras['repository']
         scm = extras['scm']
         make_lock = extras['make_lock']
+        locked_by = extras['locked_by']
         ip = extras['ip']
     elif 'username' in rc_extras:
         username = rc_extras['username']
         repository = rc_extras['repository']
         scm = rc_extras['scm']
         make_lock = rc_extras['make_lock']
+        locked_by = rc_extras['locked_by']
         ip = rc_extras['ip']
     else:
         raise Exception('Missing data in repo.ui and os.environ')
@@ -185,6 +201,12 @@
         #msg = 'Made lock on repo `%s`' % repository
         #sys.stdout.write(msg)
 
+    if locked_by[0]:
+        locked_by = User.get(locked_by[0]).username
+        _http_ret = HTTPLockedRC(repository, locked_by)
+        if str(_http_ret.code).startswith('2'):
+            #2xx Codes don't raise exceptions
+            sys.stdout.write(_http_ret.title)
     return 0
 
 
@@ -207,12 +229,14 @@
         repository = extras['repository']
         scm = extras['scm']
         make_lock = extras['make_lock']
+        locked_by = extras['locked_by']
         action = extras['action']
     elif 'username' in rc_extras:
         username = rc_extras['username']
         repository = rc_extras['repository']
         scm = rc_extras['scm']
         make_lock = rc_extras['make_lock']
+        locked_by = rc_extras['locked_by']
         action = extras['action']
     else:
         raise Exception('Missing data in repo.ui and os.environ')
@@ -257,6 +281,13 @@
         msg = 'Released lock on repo `%s`\n' % repository
         sys.stdout.write(msg)
 
+    if locked_by[0]:
+        locked_by = User.get(locked_by[0]).username
+        _http_ret = HTTPLockedRC(repository, locked_by)
+        if str(_http_ret.code).startswith('2'):
+            #2xx Codes don't raise exceptions
+            sys.stdout.write(_http_ret.title)
+
     return 0
 
 
--- a/rhodecode/lib/middleware/simplegit.py	Sun Mar 10 21:24:11 2013 +0100
+++ b/rhodecode/lib/middleware/simplegit.py	Sun Mar 10 22:53:25 2013 +0100
@@ -234,7 +234,8 @@
             app = self.__make_app(repo_name, repo_path, extras)
             return app(environ, start_response)
         except HTTPLockedRC, e:
-            log.debug('Repository LOCKED ret code 423!')
+            _code = CONFIG.get('lock_ret_code')
+            log.debug('Repository LOCKED ret code %s!' % (_code))
             return e(environ, start_response)
         except Exception:
             log.error(traceback.format_exc())
--- a/rhodecode/lib/middleware/simplehg.py	Sun Mar 10 21:24:11 2013 +0100
+++ b/rhodecode/lib/middleware/simplehg.py	Sun Mar 10 22:53:25 2013 +0100
@@ -199,7 +199,8 @@
             if str(e).find('not found') != -1:
                 return HTTPNotFound()(environ, start_response)
         except HTTPLockedRC, e:
-            log.debug('Repository LOCKED ret code 423!')
+            _code = CONFIG.get('lock_ret_code')
+            log.debug('Repository LOCKED ret code %s!' % (_code))
             return e(environ, start_response)
         except Exception:
             log.error(traceback.format_exc())