##// END OF EJS Templates
git-lfs: push settings to git-lfs backend stored inside our rhodecode settings...
marcink -
r1571:de4b3926 default
parent child Browse files
Show More
@@ -1,153 +1,155 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
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 Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 """
22 22 SimpleGit middleware for handling git protocol request (push/clone etc.)
23 23 It's implemented with basic auth function
24 24 """
25 25 import os
26 26 import re
27 27 import logging
28 28 import urlparse
29 29
30 30 import rhodecode
31 from rhodecode.lib import utils
31 32 from rhodecode.lib import utils2
32 33 from rhodecode.lib.middleware import simplevcs
33 34
34 35 log = logging.getLogger(__name__)
35 36
36 37
37 38 GIT_PROTO_PAT = re.compile(
38 39 r'^/(.+)/(info/refs|info/lfs/(.+)|git-upload-pack|git-receive-pack)')
39 40 GIT_LFS_PROTO_PAT = re.compile(r'^/(.+)/(info/lfs/(.+))')
40 41
41 42
42 43 def default_lfs_store():
43 44 """
44 45 Default lfs store location, it's consistent with Mercurials large file
45 46 store which is in .cache/largefiles
46 47 """
47 48 from rhodecode.lib.vcs.backends.git import lfs_store
48 49 user_home = os.path.expanduser("~")
49 50 return lfs_store(user_home)
50 51
51 52
52 53 class SimpleGit(simplevcs.SimpleVCS):
53 54
54 55 SCM = 'git'
55 56
56 57 def _get_repository_name(self, environ):
57 58 """
58 59 Gets repository name out of PATH_INFO header
59 60
60 61 :param environ: environ where PATH_INFO is stored
61 62 """
62 63 repo_name = GIT_PROTO_PAT.match(environ['PATH_INFO']).group(1)
63 64 # for GIT LFS, and bare format strip .git suffix from names
64 65 if repo_name.endswith('.git'):
65 66 repo_name = repo_name[:-4]
66 67 return repo_name
67 68
68 69 def _get_lfs_action(self, path, request_method):
69 70 """
70 71 return an action based on LFS requests type.
71 72 Those routes are handled inside vcsserver app.
72 73
73 74 batch -> POST to /info/lfs/objects/batch => PUSH/PULL
74 75 batch is based on the `operation.
75 76 that could be download or upload, but those are only
76 77 instructions to fetch so we return pull always
77 78
78 79 download -> GET to /info/lfs/{oid} => PULL
79 80 upload -> PUT to /info/lfs/{oid} => PUSH
80 81
81 82 verification -> POST to /info/lfs/verify => PULL
82 83
83 84 """
84 85
85 86 match_obj = GIT_LFS_PROTO_PAT.match(path)
86 87 _parts = match_obj.groups()
87 88 repo_name, path, operation = _parts
88 89 log.debug(
89 90 'LFS: detecting operation based on following '
90 91 'data: %s, req_method:%s', _parts, request_method)
91 92
92 93 if operation == 'verify':
93 94 return 'pull'
94 95 elif operation == 'objects/batch':
95 96 # batch sends back instructions for API to dl/upl we report it
96 97 # as pull
97 98 if request_method == 'POST':
98 99 return 'pull'
99 100
100 101 elif operation:
101 102 # probably a OID, upload is PUT, download a GET
102 103 if request_method == 'GET':
103 104 return 'pull'
104 105 else:
105 106 return 'push'
106 107
107 108 # if default not found require push, as action
108 109 return 'push'
109 110
110 111 _ACTION_MAPPING = {
111 112 'git-receive-pack': 'push',
112 113 'git-upload-pack': 'pull',
113 114 }
114 115
115 116 def _get_action(self, environ):
116 117 """
117 118 Maps git request commands into a pull or push command.
118 119 In case of unknown/unexpected data, it returns 'pull' to be safe.
119 120
120 121 :param environ:
121 122 """
122 123 path = environ['PATH_INFO']
123 124
124 125 if path.endswith('/info/refs'):
125 126 query = urlparse.parse_qs(environ['QUERY_STRING'])
126 127 service_cmd = query.get('service', [''])[0]
127 128 return self._ACTION_MAPPING.get(service_cmd, 'pull')
128 129
129 130 elif GIT_LFS_PROTO_PAT.match(environ['PATH_INFO']):
130 131 return self._get_lfs_action(
131 132 environ['PATH_INFO'], environ['REQUEST_METHOD'])
132 133
133 134 elif path.endswith('/git-receive-pack'):
134 135 return 'push'
135 136 elif path.endswith('/git-upload-pack'):
136 137 return 'pull'
137 138
138 139 return 'pull'
139 140
140 141 def _create_wsgi_app(self, repo_path, repo_name, config):
141 142 return self.scm_app.create_git_wsgi_app(
142 143 repo_path, repo_name, config)
143 144
144 145 def _create_config(self, extras, repo_name):
145 146 extras['git_update_server_info'] = utils2.str2bool(
146 147 rhodecode.CONFIG.get('git_update_server_info'))
147 148
148 # TODO(marcink): controll this via DB settings, store and enabled-per
149 # repo settings
149 config = utils.make_db_config(repo=repo_name)
150 custom_store = config.get('vcs_git_lfs', 'store_location')
150 151
151 extras['git_lfs_enabled'] = True
152 extras['git_lfs_store_path'] = default_lfs_store()
152 extras['git_lfs_enabled'] = utils2.str2bool(
153 config.get('vcs_git_lfs', 'enabled'))
154 extras['git_lfs_store_path'] = custom_store or default_lfs_store()
153 155 return extras
General Comments 0
You need to be logged in to leave comments. Login now