##// END OF EJS Templates
hooks: make sure exist_ok is used for multiprocess errors
super-admin -
r1120:29f87dc0 python3
parent child Browse files
Show More
@@ -1,202 +1,202 b''
1 1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 2 # Copyright (C) 2014-2020 RhodeCode GmbH
3 3 #
4 4 # This program is free software; you can redistribute it and/or modify
5 5 # it under the terms of the GNU General Public License as published by
6 6 # the Free Software Foundation; either version 3 of the License, or
7 7 # (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software Foundation,
16 16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 17
18 18 import re
19 19 import os
20 20 import sys
21 21 import datetime
22 22 import logging
23 23 import pkg_resources
24 24
25 25 import vcsserver
26 26 from vcsserver.str_utils import safe_bytes
27 27
28 28 log = logging.getLogger(__name__)
29 29
30 30
31 31 def get_git_hooks_path(repo_path, bare):
32 32 hooks_path = os.path.join(repo_path, 'hooks')
33 33 if not bare:
34 34 hooks_path = os.path.join(repo_path, '.git', 'hooks')
35 35
36 36 return hooks_path
37 37
38 38
39 39 def install_git_hooks(repo_path, bare, executable=None, force_create=False):
40 40 """
41 41 Creates a RhodeCode hook inside a git repository
42 42
43 43 :param repo_path: path to repository
44 44 :param executable: binary executable to put in the hooks
45 45 :param force_create: Create even if same name hook exists
46 46 """
47 47 executable = executable or sys.executable
48 48 hooks_path = get_git_hooks_path(repo_path, bare)
49 49
50 50 if not os.path.isdir(hooks_path):
51 os.makedirs(hooks_path, mode=0o777)
51 os.makedirs(hooks_path, mode=0o777, exist_ok=True)
52 52
53 53 tmpl_post = pkg_resources.resource_string(
54 54 'vcsserver', '/'.join(
55 55 ('hook_utils', 'hook_templates', 'git_post_receive.py.tmpl')))
56 56 tmpl_pre = pkg_resources.resource_string(
57 57 'vcsserver', '/'.join(
58 58 ('hook_utils', 'hook_templates', 'git_pre_receive.py.tmpl')))
59 59
60 60 path = '' # not used for now
61 61 timestamp = datetime.datetime.utcnow().isoformat()
62 62
63 63 for h_type, template in [('pre', tmpl_pre), ('post', tmpl_post)]:
64 64 log.debug('Installing git hook in repo %s', repo_path)
65 65 _hook_file = os.path.join(hooks_path, '%s-receive' % h_type)
66 66 _rhodecode_hook = check_rhodecode_hook(_hook_file)
67 67
68 68 if _rhodecode_hook or force_create:
69 69 log.debug('writing git %s hook file at %s !', h_type, _hook_file)
70 70 try:
71 71 with open(_hook_file, 'wb') as f:
72 72 template = template.replace(b'_TMPL_', safe_bytes(vcsserver.__version__))
73 73 template = template.replace(b'_DATE_', safe_bytes(timestamp))
74 74 template = template.replace(b'_ENV_', safe_bytes(executable))
75 75 template = template.replace(b'_PATH_', safe_bytes(path))
76 76 f.write(template)
77 77 os.chmod(_hook_file, 0o755)
78 78 except IOError:
79 79 log.exception('error writing hook file %s', _hook_file)
80 80 else:
81 81 log.debug('skipping writing hook file')
82 82
83 83 return True
84 84
85 85
86 86 def get_svn_hooks_path(repo_path):
87 87 hooks_path = os.path.join(repo_path, 'hooks')
88 88
89 89 return hooks_path
90 90
91 91
92 92 def install_svn_hooks(repo_path, executable=None, force_create=False):
93 93 """
94 94 Creates RhodeCode hooks inside a svn repository
95 95
96 96 :param repo_path: path to repository
97 97 :param executable: binary executable to put in the hooks
98 98 :param force_create: Create even if same name hook exists
99 99 """
100 100 executable = executable or sys.executable
101 101 hooks_path = get_svn_hooks_path(repo_path)
102 102 if not os.path.isdir(hooks_path):
103 os.makedirs(hooks_path, mode=0o777)
103 os.makedirs(hooks_path, mode=0o777, exist_ok=True)
104 104
105 105 tmpl_post = pkg_resources.resource_string(
106 106 'vcsserver', '/'.join(
107 107 ('hook_utils', 'hook_templates', 'svn_post_commit_hook.py.tmpl')))
108 108 tmpl_pre = pkg_resources.resource_string(
109 109 'vcsserver', '/'.join(
110 110 ('hook_utils', 'hook_templates', 'svn_pre_commit_hook.py.tmpl')))
111 111
112 112 path = '' # not used for now
113 113 timestamp = datetime.datetime.utcnow().isoformat()
114 114
115 115 for h_type, template in [('pre', tmpl_pre), ('post', tmpl_post)]:
116 116 log.debug('Installing svn hook in repo %s', repo_path)
117 117 _hook_file = os.path.join(hooks_path, '%s-commit' % h_type)
118 118 _rhodecode_hook = check_rhodecode_hook(_hook_file)
119 119
120 120 if _rhodecode_hook or force_create:
121 121 log.debug('writing svn %s hook file at %s !', h_type, _hook_file)
122 122
123 123 try:
124 124 with open(_hook_file, 'wb') as f:
125 125 template = template.replace(b'_TMPL_', safe_bytes(vcsserver.__version__))
126 126 template = template.replace(b'_DATE_', safe_bytes(timestamp))
127 127 template = template.replace(b'_ENV_', safe_bytes(executable))
128 128 template = template.replace(b'_PATH_', safe_bytes(path))
129 129
130 130 f.write(template)
131 131 os.chmod(_hook_file, 0o755)
132 132 except IOError:
133 133 log.exception('error writing hook file %s', _hook_file)
134 134 else:
135 135 log.debug('skipping writing hook file')
136 136
137 137 return True
138 138
139 139
140 140 def get_version_from_hook(hook_path):
141 141 version = b''
142 142 hook_content = read_hook_content(hook_path)
143 matches = re.search(rb'(?:RC_HOOK_VER)\s*=\s*(.*)', hook_content)
143 matches = re.search(rb'RC_HOOK_VER\s*=\s*(.*)', hook_content)
144 144 if matches:
145 145 try:
146 146 version = matches.groups()[0]
147 147 log.debug('got version %s from hooks.', version)
148 148 except Exception:
149 149 log.exception("Exception while reading the hook version.")
150 150 return version.replace(b"'", b"")
151 151
152 152
153 153 def check_rhodecode_hook(hook_path):
154 154 """
155 155 Check if the hook was created by RhodeCode
156 156 """
157 157 if not os.path.exists(hook_path):
158 158 return True
159 159
160 160 log.debug('hook exists, checking if it is from RhodeCode')
161 161
162 162 version = get_version_from_hook(hook_path)
163 163 if version:
164 164 return True
165 165
166 166 return False
167 167
168 168
169 169 def read_hook_content(hook_path) -> bytes:
170 170 content = b''
171 171 if os.path.isfile(hook_path):
172 172 with open(hook_path, 'rb') as f:
173 173 content = f.read()
174 174 return content
175 175
176 176
177 177 def get_git_pre_hook_version(repo_path, bare):
178 178 hooks_path = get_git_hooks_path(repo_path, bare)
179 179 _hook_file = os.path.join(hooks_path, 'pre-receive')
180 180 version = get_version_from_hook(_hook_file)
181 181 return version
182 182
183 183
184 184 def get_git_post_hook_version(repo_path, bare):
185 185 hooks_path = get_git_hooks_path(repo_path, bare)
186 186 _hook_file = os.path.join(hooks_path, 'post-receive')
187 187 version = get_version_from_hook(_hook_file)
188 188 return version
189 189
190 190
191 191 def get_svn_pre_hook_version(repo_path):
192 192 hooks_path = get_svn_hooks_path(repo_path)
193 193 _hook_file = os.path.join(hooks_path, 'pre-commit')
194 194 version = get_version_from_hook(_hook_file)
195 195 return version
196 196
197 197
198 198 def get_svn_post_hook_version(repo_path):
199 199 hooks_path = get_svn_hooks_path(repo_path)
200 200 _hook_file = os.path.join(hooks_path, 'post-commit')
201 201 version = get_version_from_hook(_hook_file)
202 202 return version
General Comments 0
You need to be logged in to leave comments. Login now