##// END OF EJS Templates
fix: lfs chunked uploads....
fix: lfs chunked uploads. When testing large file uploads it's found that gunicorn raises NoMoreData instead of returning value. This fixes the problem and doesn't show excesive exceptions for no reason. Previously file upload still worked but spawned errors in logs

File last commit:

r1261:0f8db01d default
r1280:b2259b07 default
Show More
__init__.py
238 lines | 8.7 KiB | text/x-python | PythonLexer
svn: added support for hooks management of git and subversion....
r407 # RhodeCode VCSServer provides access to different vcs backends via network.
source-code: updated copyrights to 2023
r1126 # Copyright (C) 2014-2023 RhodeCode GmbH
svn: added support for hooks management of git and subversion....
r407 #
# 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 3 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
fix(svn-hooks): fixed problem with svn subprocess execution fixes RCCE-62
r1214
svn: added support for hooks management of git and subversion....
r407 import re
import os
import sys
import datetime
import logging
import pkg_resources
import vcsserver
fix(svn-hooks): fixed problem with svn subprocess execution fixes RCCE-62
r1214 import vcsserver.settings
core: moved str_utils and type_utils to lib so it's consistent with ce, and easier to sync up codebases
r1249 from vcsserver.lib.str_utils import safe_bytes
svn: added support for hooks management of git and subversion....
r407
log = logging.getLogger(__name__)
fix(hooks): make compat for WSL filesystem better by explicity only changing permissions if they are lower at creation time.
r1186 HOOKS_DIR_MODE = 0o755
HOOKS_FILE_MODE = 0o755
def set_permissions_if_needed(path_to_check, perms: oct):
# Get current permissions
current_permissions = os.stat(path_to_check).st_mode & 0o777 # Extract permission bits
# Check if current permissions are lower than required
if current_permissions < int(perms):
# Change the permissions if they are lower than required
os.chmod(path_to_check, perms)
svn: added support for hooks management of git and subversion....
r407
hooks: expose logic to fetch hook file information.
r623 def get_git_hooks_path(repo_path, bare):
hooks_path = os.path.join(repo_path, 'hooks')
if not bare:
hooks_path = os.path.join(repo_path, '.git', 'hooks')
return hooks_path
svn: added support for hooks management of git and subversion....
r407 def install_git_hooks(repo_path, bare, executable=None, force_create=False):
"""
Creates a RhodeCode hook inside a git repository
:param repo_path: path to repository
fix(hooks): improve the code that manages hooks dir and files to be more prone to permissions issues
r1179 :param bare: defines if repository is considered a bare git repo
svn: added support for hooks management of git and subversion....
r407 :param executable: binary executable to put in the hooks
fix(hooks): improve the code that manages hooks dir and files to be more prone to permissions issues
r1179 :param force_create: Creates even if the same name hook exists
svn: added support for hooks management of git and subversion....
r407 """
executable = executable or sys.executable
hooks: expose logic to fetch hook file information.
r623 hooks_path = get_git_hooks_path(repo_path, bare)
fix(hooks): improve the code that manages hooks dir and files to be more prone to permissions issues
r1179 # we always call it to ensure dir exists and it has a proper mode
if not os.path.exists(hooks_path):
# If it doesn't exist, create a new directory with the specified mode
fix(hooks): make compat for WSL filesystem better by explicity only changing permissions if they are lower at creation time.
r1186 os.makedirs(hooks_path, mode=HOOKS_DIR_MODE, exist_ok=True)
# If it exists, change the directory's mode to the specified mode
set_permissions_if_needed(hooks_path, perms=HOOKS_DIR_MODE)
svn: added support for hooks management of git and subversion....
r407
tmpl_post = pkg_resources.resource_string(
'vcsserver', '/'.join(
('hook_utils', 'hook_templates', 'git_post_receive.py.tmpl')))
tmpl_pre = pkg_resources.resource_string(
'vcsserver', '/'.join(
('hook_utils', 'hook_templates', 'git_pre_receive.py.tmpl')))
path = '' # not used for now
timestamp = datetime.datetime.utcnow().isoformat()
for h_type, template in [('pre', tmpl_pre), ('post', tmpl_post)]:
log.debug('Installing git hook in repo %s', repo_path)
lint: auto-fixes
r1152 _hook_file = os.path.join(hooks_path, f'{h_type}-receive')
svn: added support for hooks management of git and subversion....
r407 _rhodecode_hook = check_rhodecode_hook(_hook_file)
if _rhodecode_hook or force_create:
log.debug('writing git %s hook file at %s !', h_type, _hook_file)
fix(svn): svn events fixes
r1261 env_expand = str([
('RC_INI_FILE', vcsserver.CONFIG['__file__']),
('RC_CORE_BINARY_DIR', vcsserver.settings.BINARY_DIR),
('RC_GIT_EXECUTABLE', vcsserver.settings.GIT_EXECUTABLE()),
('RC_SVN_EXECUTABLE', vcsserver.settings.SVN_EXECUTABLE()),
('RC_SVNLOOK_EXECUTABLE', vcsserver.settings.SVNLOOK_EXECUTABLE()),
])
svn: added support for hooks management of git and subversion....
r407 try:
with open(_hook_file, 'wb') as f:
fix(svn): svn events fixes
r1261 template = template.replace(b'_OS_EXPAND_', safe_bytes(env_expand))
fix(core): don't rely on pkgutil to extract the version info of project
r1188 template = template.replace(b'_TMPL_', safe_bytes(vcsserver.get_version()))
python3: code change for py3 support...
r1048 template = template.replace(b'_DATE_', safe_bytes(timestamp))
template = template.replace(b'_ENV_', safe_bytes(executable))
template = template.replace(b'_PATH_', safe_bytes(path))
svn: added support for hooks management of git and subversion....
r407 f.write(template)
fix(hooks): make compat for WSL filesystem better by explicity only changing permissions if they are lower at creation time.
r1186 set_permissions_if_needed(_hook_file, perms=HOOKS_FILE_MODE)
vcsserver: modernize code for python3
r1130 except OSError:
svn: added support for hooks management of git and subversion....
r407 log.exception('error writing hook file %s', _hook_file)
else:
log.debug('skipping writing hook file')
return True
hooks: expose logic to fetch hook file information.
r623 def get_svn_hooks_path(repo_path):
hooks_path = os.path.join(repo_path, 'hooks')
return hooks_path
svn: added support for hooks management of git and subversion....
r407 def install_svn_hooks(repo_path, executable=None, force_create=False):
"""
Creates RhodeCode hooks inside a svn repository
:param repo_path: path to repository
:param executable: binary executable to put in the hooks
:param force_create: Create even if same name hook exists
"""
executable = executable or sys.executable
hooks: expose logic to fetch hook file information.
r623 hooks_path = get_svn_hooks_path(repo_path)
svn: added support for hooks management of git and subversion....
r407 if not os.path.isdir(hooks_path):
hooks: make sure exist_ok is used for multiprocess errors
r1120 os.makedirs(hooks_path, mode=0o777, exist_ok=True)
svn: added support for hooks management of git and subversion....
r407
tmpl_post = pkg_resources.resource_string(
'vcsserver', '/'.join(
('hook_utils', 'hook_templates', 'svn_post_commit_hook.py.tmpl')))
tmpl_pre = pkg_resources.resource_string(
'vcsserver', '/'.join(
('hook_utils', 'hook_templates', 'svn_pre_commit_hook.py.tmpl')))
path = '' # not used for now
timestamp = datetime.datetime.utcnow().isoformat()
for h_type, template in [('pre', tmpl_pre), ('post', tmpl_post)]:
log.debug('Installing svn hook in repo %s', repo_path)
lint: auto-fixes
r1152 _hook_file = os.path.join(hooks_path, f'{h_type}-commit')
svn: added support for hooks management of git and subversion....
r407 _rhodecode_hook = check_rhodecode_hook(_hook_file)
if _rhodecode_hook or force_create:
log.debug('writing svn %s hook file at %s !', h_type, _hook_file)
fix(svn-hooks): fixed problem with svn subprocess execution fixes RCCE-62
r1214 env_expand = str([
fix(svn): svn events fixes
r1261 ('RC_INI_FILE', vcsserver.CONFIG['__file__']),
fix(svn-hooks): fixed problem with svn subprocess execution fixes RCCE-62
r1214 ('RC_CORE_BINARY_DIR', vcsserver.settings.BINARY_DIR),
fix(svn): fixed problems with svn hooks binary dir not beeing propagates in mod_dav_svn
r1230 ('RC_GIT_EXECUTABLE', vcsserver.settings.GIT_EXECUTABLE()),
('RC_SVN_EXECUTABLE', vcsserver.settings.SVN_EXECUTABLE()),
('RC_SVNLOOK_EXECUTABLE', vcsserver.settings.SVNLOOK_EXECUTABLE()),
fix(svn-hooks): fixed problem with svn subprocess execution fixes RCCE-62
r1214 ])
svn: added support for hooks management of git and subversion....
r407 try:
with open(_hook_file, 'wb') as f:
fix(svn): svn events fixes
r1261 template = template.replace(b'_OS_EXPAND_', safe_bytes(env_expand))
fix(core): don't rely on pkgutil to extract the version info of project
r1188 template = template.replace(b'_TMPL_', safe_bytes(vcsserver.get_version()))
python3: code change for py3 support...
r1048 template = template.replace(b'_DATE_', safe_bytes(timestamp))
template = template.replace(b'_ENV_', safe_bytes(executable))
template = template.replace(b'_PATH_', safe_bytes(path))
svn: added support for hooks management of git and subversion....
r407
f.write(template)
code: fix deprecated octal usage for py3 compatability.
r590 os.chmod(_hook_file, 0o755)
vcsserver: modernize code for python3
r1130 except OSError:
svn: added support for hooks management of git and subversion....
r407 log.exception('error writing hook file %s', _hook_file)
else:
log.debug('skipping writing hook file')
return True
hooks: expose logic to fetch hook file information.
r623 def get_version_from_hook(hook_path):
python3: code change for py3 support...
r1048 version = b''
hooks: expose logic to fetch hook file information.
r623 hook_content = read_hook_content(hook_path)
hooks: make sure exist_ok is used for multiprocess errors
r1120 matches = re.search(rb'RC_HOOK_VER\s*=\s*(.*)', hook_content)
hooks: expose logic to fetch hook file information.
r623 if matches:
try:
version = matches.groups()[0]
log.debug('got version %s from hooks.', version)
except Exception:
log.exception("Exception while reading the hook version.")
python3: code change for py3 support...
r1048 return version.replace(b"'", b"")
hooks: expose logic to fetch hook file information.
r623
svn: added support for hooks management of git and subversion....
r407 def check_rhodecode_hook(hook_path):
"""
Check if the hook was created by RhodeCode
"""
if not os.path.exists(hook_path):
return True
hooks: expose logic to fetch hook file information.
r623 log.debug('hook exists, checking if it is from RhodeCode')
version = get_version_from_hook(hook_path)
if version:
return True
svn: added support for hooks management of git and subversion....
r407
return False
vcsserver: fixed some bytes issues with status command/read hooks info endpoint
r1066 def read_hook_content(hook_path) -> bytes:
content = b''
hooks: do not crash when hook files are empty
r691 if os.path.isfile(hook_path):
with open(hook_path, 'rb') as f:
content = f.read()
svn: added support for hooks management of git and subversion....
r407 return content
hooks: expose logic to fetch hook file information.
r623
def get_git_pre_hook_version(repo_path, bare):
hooks_path = get_git_hooks_path(repo_path, bare)
_hook_file = os.path.join(hooks_path, 'pre-receive')
version = get_version_from_hook(_hook_file)
return version
def get_git_post_hook_version(repo_path, bare):
hooks_path = get_git_hooks_path(repo_path, bare)
_hook_file = os.path.join(hooks_path, 'post-receive')
version = get_version_from_hook(_hook_file)
return version
def get_svn_pre_hook_version(repo_path):
hooks_path = get_svn_hooks_path(repo_path)
_hook_file = os.path.join(hooks_path, 'pre-commit')
version = get_version_from_hook(_hook_file)
return version
def get_svn_post_hook_version(repo_path):
hooks_path = get_svn_hooks_path(repo_path)
_hook_file = os.path.join(hooks_path, 'post-commit')
version = get_version_from_hook(_hook_file)
return version