Project

General

Profile

HowTo configure Redmine for advanced git integration » History » Version 24

Vladimir Skubriev, 2013-10-04 08:03

1 1 Felix Schäfer
h1. HowTo configure Redmine for advanced git integration
2
3 3 Felix Schäfer
{{>TOC}}
4
5 1 Felix Schäfer
h2. Scope
6
7 21 Mr. DTTH
_Install on Centos 6.x_
8
9 17 Mr. DTTH
This HowTo explains how to serve git repositories on apache through the http-based "git-smart-http protocol":http://progit.org/2010/03/04/smart-http.html introduced in git 1.6.6. 
10 1 Felix Schäfer
11 17 Mr. DTTH
The git-smart-http offers various advantages over ssh or git-based access: you can use redmine access control as-is, no need for extra ssh keys or whatnot, you can secure it through SSL as needed, and there's generally less problems with firewalls and https/https ports than exist with ssh and git ports. git-smart-http also doesn't have some of the drawbacks of its "dumb" predecessor, as it doesn't require any complex DAV setup.
12 1 Felix Schäfer
13 17 Mr. DTTH
This HowTo is mainly written from memory and was conducted on a setup which was already serving [[Repositories_access_control_with_apache_mod_dav_svn_and_mod_perl|svn repositories integrated with redmine]], so it might be possible that I forgot some things or take them for granted. 
14
15
This is a wiki page, feel free to correct or amend anything you find lacking :-) You can also "drop me a line":/users/3866.
16
17 7 Felix Schäfer
Another option to integrate grack with redmine is the "modified grack+redmine plugin":http://github.com/friflaj/redmine_grack or "any other grack modified for redmine":http://github.com/search?q=grack&type=Everything&repo=&langOverride=&start_value=1, though those ones lack documentation and I haven't tried them, so I can't say much about those.
18 1 Felix Schäfer
19
h2. Prerequisites
20
21
* Apache with mod_perl (access control)
22
* git (version at least 1.6.6)
23
* A way to serve git-smart-http
24 10 Hallison Vasconcelos Batista
** mod_cgi (or mod_cgid) if you want to use the stock "git-http-backend":http://www.kernel.org/pub/software/scm/git/docs/git-http-backend.html
25 1 Felix Schäfer
** a rack server if you want to use "grack":http://github.com/schacon/grack (basically a rack wrapper around the right git commands) or
26 10 Hallison Vasconcelos Batista
"git-webby":http://git.io/BU7twg (another implementation based on grack but written in Sinatra).
27 1 Felix Schäfer
28 17 Mr. DTTH
You should already have a rack server to run redmine, and that's why I chose grack as the backend and which I will describe in this tutorial. 
29 1 Felix Schäfer
30 17 Mr. DTTH
Using the stock git-http-backend should be quite straightforward though (skip the [[HowTo_configure_Redmine_for_advanced_git_integration#Install-grack|grack installation]] part and get your install with the git-http-backend going (the "git-http-backend manpage":http://www.kernel.org/pub/software/scm/git/docs/git-http-backend.html has some examples), when that's done go on with the [[HowTo_configure_Redmine_for_advanced_git_integration#Access-control|access control]] part).
31
32 20 Mr. DTTH
h2. Install Git
33
34
<pre><code class="bash">
35
yum install git
36
</code></pre>
37
38 2 Felix Schäfer
h2. Install grack
39 1 Felix Schäfer
40 3 Felix Schäfer
h3. Get the sources
41 2 Felix Schäfer
42 19 Mr. DTTH
Fetch grack from its "github repository":http://github.com/schacon/grack, I checked out mine to @/var/www/grack@
43 1 Felix Schäfer
44 19 Mr. DTTH
<pre><code class="bash">
45
cd /var/www
46
git clone http://github.com/schacon/grack.git
47
</code></pre>
48 1 Felix Schäfer
49 18 Mr. DTTH
And create a directory for repositories :
50
51
<pre><code class="bash">
52 1 Felix Schäfer
mkdir /opt/repositories
53 21 Mr. DTTH
mkdir /opt/repositories/git
54 18 Mr. DTTH
chown -R apache:apache /opt/repositories/git
55
</code></pre>
56
57 2 Felix Schäfer
h3. Configuration
58
59
Edit the @config.ru@ file and adapt it to your local configuration. @project_root@ must contain the path to the directory containing your git repositories, @git_path@ must obviously contain the path to the git, mine looks like this (on gentoo):
60 1 Felix Schäfer
61 21 Mr. DTTH
<pre><code class="bash">
62
vi /var/www/grack/config.ru
63
</code></pre>
64
65
And edit file :
66
67 2 Felix Schäfer
<pre><code class="ruby">$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/lib')
68 1 Felix Schäfer
69 2 Felix Schäfer
use Rack::ShowExceptions
70 1 Felix Schäfer
71 18 Mr. DTTH
require 'grack'
72 1 Felix Schäfer
73 18 Mr. DTTH
require 'git_adapter'
74 2 Felix Schäfer
75 18 Mr. DTTH
config = {
76
  :project_root => "/opt/repositories/git",
77 2 Felix Schäfer
  :git_path => '/usr/bin/git',
78
  :upload_pack => true,
79 1 Felix Schäfer
  :receive_pack => true,
80
}
81
82 21 Mr. DTTH
run GitHttp::App.new(config)
83
</code></pre>
84 3 Felix Schäfer
85 24 Vladimir Skubriev
If you use the latest version of grack, then may be this config.ru file is usable
86
87
88
<pre><code class="ruby">
89
90
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/lib')
91
92
use Rack::ShowExceptions
93
94
require 'grack'
95
96
require 'git_adapter'
97
98
config = {
99
  :project_root => "/opt/repositories/git",
100
  :git_path => '/usr/bin/git',
101
  :upload_pack => true,
102
  :receive_pack => true,
103
  :adapter => Grack::GitAdapter,
104
}
105
106
run Grack::App.new(config)
107
108
</code></pre>
109
110 1 Felix Schäfer
h3. Integrate with Apache
111
112 17 Mr. DTTH
You could obviously use any rack server you like at this point, but the access control mechanism @Redmine.pm@ is written for apache with mod_perl, so you will at least need to reverse proxy your rack server through apache. 
113 1 Felix Schäfer
114 17 Mr. DTTH
My rack server of choice is "passenger":http://modrails.com/ (solid performance, apache module, mostly simple configuration) and it is already configured on my system. 
115
116
As passenger installation and configuration is not within the scope of this HowTo, please refer to the "passenger documentation":http://modrails.com/documentation.html or to the passenger installation guide from your distribution.
117
118
There's a little more work to do here to get passenger to work with this, you will need to create the directories @public@ and @tmp@ in the grack directory. 
119 1 Felix Schäfer
120
Please also be aware that in the standard configuration, passenger will run the grack application with the same user and group owning the @config.ru@ file. This user must have read- and write-access as needed to the git repositories!
121
122 21 Mr. DTTH
Create directories 'public' and 'tmp' in /var/www/grack for apache :
123
124
<pre><code class="bash">
125
cd /var/www/grack
126
mkdir public
127
mkdir tmp
128
chown -R apache:apache /var/www/grack
129
</code></pre>
130
131
Edit config file "/etc/httpd/conf/httpd.conf" for support multi virtualhost by remove comment :
132
133
<pre><code class="bash">
134
NameVirtualHost *:80
135
</code></pre>
136
137
Create a file virtualhost :
138
139
<pre><code class="bash">
140
vi /etc/httpd/conf.d/git.conf
141
</code></pre>
142
143 22 Mr. DTTH
with text :
144 1 Felix Schäfer
145 22 Mr. DTTH
<pre><code class="apache">
146
<VirtualHost *:80>
147
    ServerName git.yourdomain.com
148
    DocumentRoot "/var/www/grack/public"
149
    <Directory "/var/www/grack/public">
150 1 Felix Schäfer
        Options None
151
        AllowOverride None
152 22 Mr. DTTH
        <IfVersion < 2.3 >
153 1 Felix Schäfer
        Order allow,deny
154
        Allow from all
155 22 Mr. DTTH
        </IfVersion>
156
        <IfVersion >= 2.3>
157
        Require all granted
158
        </IfVersion>
159
     </Directory>
160
 </VirtualHost>
161
</code></pre>
162 2 Felix Schäfer
163 22 Mr. DTTH
In controlpanel DNS record at domain name page, create a subdomain with name "git.yourdomain.com" and point to your IP server.
164 2 Felix Schäfer
165 22 Mr. DTTH
At this point, if you have a repository in "/opt/repositories/git/myrepo", you should be able to access it through "http://git.yourdomain.com/myrepo", for example :
166 2 Felix Schäfer
167 22 Mr. DTTH
Use a git client as Gitbash or TortoiseGit to clone repos :
168
169
<pre><code class="apache">
170
git clone http://git.yourdomain.com/myrepo
171
</code></pre>
172
173
If it successful, git on server and connection is very good!
174 3 Felix Schäfer
175
h2. Access control
176
177
You now have a working git server, albeit with no access control. Currently, the shipped perl module for access control @Redmine.pm@ (in @extra/svn/@ in your redmine directory) does not support access control for the git-smart-http protocol, the patch in #4905 aims to implement that.
178
179 11 Gregory Bartholomew
h3. Applying the patch
180 1 Felix Schäfer
181 23 Mr. DTTH
_If you are using Redmine >= 2.1.0, step over to Configuring Apache_
182
183 3 Felix Schäfer
Download the latest (or better: correct) version of the patch from #4905 to your redmine directory. In the redmine directory, apply the patch: @patch -p1 < the-patch-file.patch@ should work (if it tells you stuff about being unable to apply a hunk, the patch is incompatible with your @Redmine.pm@ version, if it says other stuff, try @patch -p0 < the-patch-file.patch@ or @patch Redmine.pm < the-patch-file.patch@, if it still borks, ask for advice on #4905).
184 1 Felix Schäfer
185
-You will possibly still need to edit the file from here, because the current version of the patch only works for repositories served from @http://git.myhost.com/git/myrepo@ though the above example uses @http://git.myhost.com/myrepo@.- This step isn't needed anymore, the patch has been updated to take the information from the @Location@ block from apache into account.
186 8 Felix Schäfer
187 3 Felix Schäfer
h3. Configuring Apache
188 17 Mr. DTTH
189 3 Felix Schäfer
You now have to make Apache aware of your new authentication module (if you already had done this step for subversion integration, you can go to the @Location@ directives directly). 
190 17 Mr. DTTH
191
Copy or link @Redmine.pm@ (from your @extra/svn/@ directory) to @/usr/lib/perl5/Apache/Redmine.pm@ (ubuntu) or wherever your distribution puts its apache perl modules (e.g. gentoo puts them in @/usr/lib64/perl5/vendor_perl/5.8.8/Apache/@, fedora puts them in @/usr/lib64/perl5/vendor_perl/Apache/@).
192 3 Felix Schäfer
193 1 Felix Schäfer
Having done that, reload apache to make sure everything in the patching phase went well (if not, remove the link or the file create in the step just before and restart apache to get apache back up, try to find the error in your Redmine.pm file). Now edit your vhost configuration to look somewhat like (same as above but with more stuff):
194
195 23 Mr. DTTH
<pre><code class="bash">
196
vi /etc/httpd/conf.d/git.conf
197
</code></pre>
198 1 Felix Schäfer
199 23 Mr. DTTH
with :
200 1 Felix Schäfer
201 23 Mr. DTTH
<pre><code class="bash">
202 1 Felix Schäfer
203 23 Mr. DTTH
<VirtualHost *:80>
204
205
    ServerName git.yourdomain.com
206
207
    DocumentRoot "/var/www/grack/public"
208
209
    <Directory "/var/www/grack/public">
210
211 1 Felix Schäfer
        Options None
212 23 Mr. DTTH
213 1 Felix Schäfer
        AllowOverride None
214 23 Mr. DTTH
215
        <IfVersion < 2.3 >
216
217 1 Felix Schäfer
        Order allow,deny
218 23 Mr. DTTH
219 1 Felix Schäfer
        Allow from all
220
221 23 Mr. DTTH
        </IfVersion>
222 1 Felix Schäfer
223 23 Mr. DTTH
        <IfVersion >= 2.3>
224 1 Felix Schäfer
225 23 Mr. DTTH
        Require all granted
226 1 Felix Schäfer
227 23 Mr. DTTH
        </IfVersion>
228 1 Felix Schäfer
229 23 Mr. DTTH
     </Directory>
230
231
     PerlLoadModule Apache::Redmine
232
    <Directory "/var/www/grack/public">
233
234
        Options None
235
236
        AllowOverride None
237
238
        <IfVersion < 2.3 >
239
240
        Order allow,deny
241
242
        Allow from all
243
244
        </IfVersion>
245
246
        <IfVersion >= 2.3>
247
248
        Require all granted
249
250
        </IfVersion>
251
252
     </Directory>
253
254
     
255
     <Location "/">
256
257
       AuthType Basic
258
259
       AuthName "Redmine git repositories"
260
261
       Require valid-user
262
263
       PerlAccessHandler Apache::Authn::Redmine::access_handler
264
       PerlAuthenHandler Apache::Authn::Redmine::authen_handler
265
   
266
       RedmineDSN "DBI:mysql:database=your_database;host=localhost:3306"
267
268
       RedmineDbUser "user_database"
269
       RedmineDbPass "password_database"       
270
       RedmineGitSmartHttp yes
271
     </Location>
272
273
 </VirtualHost>
274
</code></pre>
275
276
Restart your apache, and everything should be good and well :-)
277 13 Gregory Bartholomew
278
h2. Known issues
279
280
If you are using the stock git-http-backend directly under apache and you are finding errors like "Request not supported: '/git/your-git-repo'" in your apache error log, you may need to add "SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER" to the to the list of environment variables that you are setting in your apache configuration.  
281
282
Unfortionately, this setting may cause redmine to borke.  If so, you will need to set the variable for only the requests that are passed through git-http-backend.  One way to accomplish this is with mod_rewrite.  Below is a sample apache configuration from a Fedora 17 system that uses git-http-backend and mod_rewrite.
283
284
In httpd.conf:
285
286
<pre><code class="apache">Listen xxx.xxx.xxx.xxx:80
287
<VirtualHost xxx.xxx.xxx.xxx:80>
288
   DocumentRoot /var/www/redmine/public
289
   ServerName servername.domain:80
290
   Include conf/servername.conf
291
</VirtualHost>
292
293
Listen xxx.xxx.xxx.xxx:443
294
<VirtualHost xxx.xxx.xxx.xxx:443>
295
   DocumentRoot /var/www/redmine/public
296
   ServerName servername.domain:443
297
   Include conf/servername.conf
298
   Include conf/ssl.conf
299
</VirtualHost></code></pre>
300
301
In servername.conf:
302
303
<pre><code class="apache">PerlLoadModule Apache::Authn::Redmine
304
305
SetEnv GIT_PROJECT_ROOT /git-1/repositories
306
SetEnv GIT_HTTP_EXPORT_ALL
307
308
<IfModule mod_rewrite.c>
309
   RewriteEngine On
310 15 Gregory Bartholomew
311
   RewriteCond %{HTTPS} ^off$
312
   RewriteCond %{REQUEST_URI} !^/git-private/
313 13 Gregory Bartholomew
   RewriteRule ^.*$ https://servername.domain$0 [R=301,L]
314
   RewriteRule ^/git/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$ /git-1/repositories/$1 [L]
315
   RewriteRule ^/git/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /git-1/repositories/$1 [L]
316
   RewriteRule ^/git/(.*)$ /usr/libexec/git-core/git-http-backend/$1 [E=REMOTE_USER:$REDIRECT_REMOTE_USER,H=cgi-script,L]
317
</IfModule>
318
319
<Directory /usr/libexec/git-core>
320
   <Files "git-http-backend">
321
      Options +ExecCGI
322
   </Files>
323
</Directory>
324
325
<Location /git>
326
   AuthType Basic
327 14 Gregory Bartholomew
   AuthName "CAMPUS"
328 13 Gregory Bartholomew
   AuthBasicProvider external
329
   AuthExternal pwauth
330
   Require valid-user
331
332
   PerlAccessHandler Apache::Authn::Redmine::access_handler
333
   PerlAuthenHandler Apache::Authn::Redmine::authen_handler
334
 
335
   RedmineDSN "DBI:mysql:database=redmine;host=localhost" 
336
   RedmineDbUser "redmine" 
337
   # RedmineDbPass "password"
338
   RedmineGitSmartHttp yes
339
</Location>
340
341
Alias /git-private /git-1/repositories
342
343
<Location /git-private>
344
   Order deny,allow
345
   Deny from all
346
   <Limit GET PROPFIND OPTIONS REPORT>
347
      Options Indexes FollowSymLinks MultiViews
348
      Allow from 127.0.0.1
349
      Allow from localhost
350
   </Limit>
351
</Location>
352
353
<Directory "/var/www/redmine/public">
354
   RailsEnv production
355
   RailsBaseURI /
356
357
   Options -MultiViews
358
   AllowOverride All
359
</Directory></code></pre>
360
361
In conf/ssl.conf:
362
363
<pre><code class="apache">LogLevel warn
364
SSLEngine on
365
SSLProtocol all -SSLv2
366
SSLCipherSuite RC4-SHA:AES128-SHA:ALL:!ADH:!EXP:!LOW:!MD5:!SSLV2:!NULL
367
SSLCertificateFile /etc/pki/tls/certs/your-server.crt
368
SSLCertificateKeyFile /etc/pki/tls/private/your-server.key
369
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
370
SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
371
372
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
373
    SSLOptions +StdEnvVars
374
</Files>
375
<Directory "/var/www/cgi-bin">
376
    SSLOptions +StdEnvVars
377
</Directory>
378 1 Felix Schäfer
379
SetEnvIf User-Agent ".*MSIE.*" \
380
         nokeepalive ssl-unclean-shutdown \
381 13 Gregory Bartholomew
         downgrade-1.0 force-response-1.0
382
</code></pre>
383
384
In conf.d/ssl.conf:
385
386 17 Mr. DTTH
<pre><code class="apache">LoadModule ssl_module modules/mod_ssl.so
387
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
388
SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)
389 13 Gregory Bartholomew
SSLSessionCacheTimeout  300
390 15 Gregory Bartholomew
SSLMutex default
391 13 Gregory Bartholomew
SSLRandomSeed startup file:/dev/urandom  256
392
SSLRandomSeed connect builtin
393 1 Felix Schäfer
SSLCryptoDevice builtin
394
</code></pre>
395
396
You will also need to have the perl modules Net::LDAP, Authen::Simple, and Authen::Simple::LDAP installed.  The first two are available in Fedora's default package repositories.  
397
398
The third must be installed after the other two and it must be obtained directly from cpan.  Below are the commands that I used to install these packages on Fedora 17.
399
400
yum -y install gcc make perl-LDAP perl-Authen-Simple
401
cpan
402
cpan> install Authen::Simple::LDAP