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

Mr. DTTH, 2013-08-08 05:16

1 1 Felix Schäfer
h1. HowTo configure Redmine for advanced git integration
2 1 Felix Schäfer
3 3 Felix Schäfer
{{>TOC}}
4 3 Felix Schäfer
5 1 Felix Schäfer
h2. Scope
6 1 Felix Schäfer
7 21 Mr. DTTH
_Install on Centos 6.x_
8 21 Mr. DTTH
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 17 Mr. DTTH
15 17 Mr. DTTH
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 Mr. DTTH
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 1 Felix Schäfer
h2. Prerequisites
20 1 Felix Schäfer
21 1 Felix Schäfer
* Apache with mod_perl (access control)
22 1 Felix Schäfer
* git (version at least 1.6.6)
23 1 Felix Schäfer
* 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 17 Mr. DTTH
32 20 Mr. DTTH
h2. Install Git
33 20 Mr. DTTH
34 20 Mr. DTTH
<pre><code class="bash">
35 20 Mr. DTTH
yum install git
36 20 Mr. DTTH
</code></pre>
37 20 Mr. DTTH
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 19 Mr. DTTH
cd /var/www
46 19 Mr. DTTH
git clone http://github.com/schacon/grack.git
47 19 Mr. DTTH
</code></pre>
48 1 Felix Schäfer
49 18 Mr. DTTH
And create a directory for repositories :
50 18 Mr. DTTH
51 18 Mr. DTTH
<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 18 Mr. DTTH
</code></pre>
56 18 Mr. DTTH
57 2 Felix Schäfer
h3. Configuration
58 2 Felix Schäfer
59 2 Felix Schäfer
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 21 Mr. DTTH
vi /var/www/grack/config.ru
63 21 Mr. DTTH
</code></pre>
64 21 Mr. DTTH
65 21 Mr. DTTH
And edit file :
66 21 Mr. DTTH
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 18 Mr. DTTH
  :project_root => "/opt/repositories/git",
77 2 Felix Schäfer
  :git_path => '/usr/bin/git',
78 2 Felix Schäfer
  :upload_pack => true,
79 1 Felix Schäfer
  :receive_pack => true,
80 1 Felix Schäfer
}
81 1 Felix Schäfer
82 21 Mr. DTTH
run GitHttp::App.new(config)
83 21 Mr. DTTH
</code></pre>
84 3 Felix Schäfer
85 1 Felix Schäfer
h3. Integrate with Apache
86 1 Felix Schäfer
87 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. 
88 1 Felix Schäfer
89 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. 
90 17 Mr. DTTH
91 17 Mr. DTTH
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.
92 17 Mr. DTTH
93 17 Mr. DTTH
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. 
94 1 Felix Schäfer
95 1 Felix Schäfer
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!
96 1 Felix Schäfer
97 21 Mr. DTTH
Create directories 'public' and 'tmp' in /var/www/grack for apache :
98 21 Mr. DTTH
99 21 Mr. DTTH
<pre><code class="bash">
100 21 Mr. DTTH
cd /var/www/grack
101 21 Mr. DTTH
mkdir public
102 21 Mr. DTTH
mkdir tmp
103 21 Mr. DTTH
chown -R apache:apache /var/www/grack
104 21 Mr. DTTH
</code></pre>
105 21 Mr. DTTH
106 21 Mr. DTTH
Edit config file "/etc/httpd/conf/httpd.conf" for support multi virtualhost by remove comment :
107 21 Mr. DTTH
108 21 Mr. DTTH
<pre><code class="bash">
109 21 Mr. DTTH
NameVirtualHost *:80
110 21 Mr. DTTH
</code></pre>
111 21 Mr. DTTH
112 21 Mr. DTTH
Create a file virtualhost :
113 21 Mr. DTTH
114 21 Mr. DTTH
<pre><code class="bash">
115 21 Mr. DTTH
vi /etc/httpd/conf.d/git.conf
116 21 Mr. DTTH
</code></pre>
117 21 Mr. DTTH
118 22 Mr. DTTH
with text :
119 1 Felix Schäfer
120 22 Mr. DTTH
<pre><code class="apache">
121 22 Mr. DTTH
<VirtualHost *:80>
122 22 Mr. DTTH
    ServerName git.yourdomain.com
123 22 Mr. DTTH
    DocumentRoot "/var/www/grack/public"
124 22 Mr. DTTH
    <Directory "/var/www/grack/public">
125 1 Felix Schäfer
        Options None
126 1 Felix Schäfer
        AllowOverride None
127 22 Mr. DTTH
        <IfVersion < 2.3 >
128 1 Felix Schäfer
        Order allow,deny
129 1 Felix Schäfer
        Allow from all
130 22 Mr. DTTH
        </IfVersion>
131 22 Mr. DTTH
        <IfVersion >= 2.3>
132 22 Mr. DTTH
        Require all granted
133 22 Mr. DTTH
        </IfVersion>
134 22 Mr. DTTH
     </Directory>
135 22 Mr. DTTH
 </VirtualHost>
136 22 Mr. DTTH
</code></pre>
137 2 Felix Schäfer
138 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.
139 2 Felix Schäfer
140 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 :
141 2 Felix Schäfer
142 22 Mr. DTTH
Use a git client as Gitbash or TortoiseGit to clone repos :
143 22 Mr. DTTH
144 22 Mr. DTTH
<pre><code class="apache">
145 22 Mr. DTTH
git clone http://git.yourdomain.com/myrepo
146 22 Mr. DTTH
</code></pre>
147 22 Mr. DTTH
148 22 Mr. DTTH
If it successful, git on server and connection is very good!
149 3 Felix Schäfer
150 3 Felix Schäfer
h2. Access control
151 3 Felix Schäfer
152 3 Felix Schäfer
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.
153 3 Felix Schäfer
154 11 Gregory Bartholomew
h3. Applying the patch
155 1 Felix Schäfer
156 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).
157 1 Felix Schäfer
158 1 Felix Schäfer
-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.
159 8 Felix Schäfer
160 3 Felix Schäfer
h3. Configuring Apache
161 17 Mr. DTTH
162 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). 
163 17 Mr. DTTH
164 17 Mr. DTTH
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/@).
165 3 Felix Schäfer
166 3 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):
167 3 Felix Schäfer
168 3 Felix Schäfer
<pre><code class="apache"><VirtualHost yo.ur.i.p:80>
169 3 Felix Schäfer
    ServerName git.myhost.com
170 3 Felix Schäfer
171 3 Felix Schäfer
    ServerAdmin root@myhost.com
172 3 Felix Schäfer
    DocumentRoot "/var/www/git.myhost.com/public"
173 3 Felix Schäfer
174 3 Felix Schäfer
    PerlLoadModule Apache::Redmine
175 3 Felix Schäfer
176 3 Felix Schäfer
    <Directory "/var/www/git.myhost.com/public">
177 3 Felix Schäfer
        Options None
178 3 Felix Schäfer
        AllowOverride None
179 3 Felix Schäfer
        Order allow,deny
180 3 Felix Schäfer
        Allow from all
181 3 Felix Schäfer
    </Directory>
182 3 Felix Schäfer
183 3 Felix Schäfer
    <Location "/">
184 3 Felix Schäfer
        AuthType Basic
185 3 Felix Schäfer
        AuthName "Redmine git repositories"
186 3 Felix Schäfer
        Require valid-user
187 3 Felix Schäfer
188 3 Felix Schäfer
        PerlAccessHandler Apache::Authn::Redmine::access_handler
189 3 Felix Schäfer
        PerlAuthenHandler Apache::Authn::Redmine::authen_handler
190 3 Felix Schäfer
191 3 Felix Schäfer
        ## for mysql
192 3 Felix Schäfer
        RedmineDSN "DBI:mysql:database=databasename;host=my.db.server"
193 3 Felix Schäfer
        ## for postgres
194 3 Felix Schäfer
        # RedmineDSN "DBI:Pg:dbname=databasename;host=my.db.server"
195 3 Felix Schäfer
        ## for SQLite3
196 3 Felix Schäfer
        # RedmineDSN "DBI:SQLite:dbname=database.db"
197 3 Felix Schäfer
198 3 Felix Schäfer
        RedmineDbUser "redmine"
199 3 Felix Schäfer
        RedmineDbPass "password"
200 1 Felix Schäfer
        RedmineGitSmartHttp yes
201 3 Felix Schäfer
    </Location>
202 1 Felix Schäfer
</VirtualHost></code></pre>
203 1 Felix Schäfer
204 3 Felix Schäfer
Reload your apache, and everything should be good and well :-)
205 3 Felix Schäfer
206 3 Felix Schäfer
h2. Known issues
207 17 Mr. DTTH
208 1 Felix Schäfer
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.  
209 17 Mr. DTTH
210 17 Mr. DTTH
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.
211 13 Gregory Bartholomew
212 13 Gregory Bartholomew
In httpd.conf:
213 13 Gregory Bartholomew
214 13 Gregory Bartholomew
<pre><code class="apache">Listen xxx.xxx.xxx.xxx:80
215 13 Gregory Bartholomew
<VirtualHost xxx.xxx.xxx.xxx:80>
216 13 Gregory Bartholomew
   DocumentRoot /var/www/redmine/public
217 13 Gregory Bartholomew
   ServerName servername.domain:80
218 13 Gregory Bartholomew
   Include conf/servername.conf
219 13 Gregory Bartholomew
</VirtualHost>
220 13 Gregory Bartholomew
221 13 Gregory Bartholomew
Listen xxx.xxx.xxx.xxx:443
222 13 Gregory Bartholomew
<VirtualHost xxx.xxx.xxx.xxx:443>
223 13 Gregory Bartholomew
   DocumentRoot /var/www/redmine/public
224 13 Gregory Bartholomew
   ServerName servername.domain:443
225 13 Gregory Bartholomew
   Include conf/servername.conf
226 13 Gregory Bartholomew
   Include conf/ssl.conf
227 13 Gregory Bartholomew
</VirtualHost></code></pre>
228 13 Gregory Bartholomew
229 13 Gregory Bartholomew
In servername.conf:
230 13 Gregory Bartholomew
231 13 Gregory Bartholomew
<pre><code class="apache">PerlLoadModule Apache::Authn::Redmine
232 13 Gregory Bartholomew
233 13 Gregory Bartholomew
SetEnv GIT_PROJECT_ROOT /git-1/repositories
234 13 Gregory Bartholomew
SetEnv GIT_HTTP_EXPORT_ALL
235 13 Gregory Bartholomew
236 13 Gregory Bartholomew
<IfModule mod_rewrite.c>
237 13 Gregory Bartholomew
   RewriteEngine On
238 13 Gregory Bartholomew
239 13 Gregory Bartholomew
   RewriteCond %{HTTPS} ^off$
240 13 Gregory Bartholomew
   RewriteCond %{REQUEST_URI} !^/git-private/
241 13 Gregory Bartholomew
   RewriteRule ^.*$ https://servername.domain$0 [R=301,L]
242 13 Gregory Bartholomew
   RewriteRule ^/git/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$ /git-1/repositories/$1 [L]
243 13 Gregory Bartholomew
   RewriteRule ^/git/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /git-1/repositories/$1 [L]
244 13 Gregory Bartholomew
   RewriteRule ^/git/(.*)$ /usr/libexec/git-core/git-http-backend/$1 [E=REMOTE_USER:$REDIRECT_REMOTE_USER,H=cgi-script,L]
245 13 Gregory Bartholomew
</IfModule>
246 13 Gregory Bartholomew
247 15 Gregory Bartholomew
<Directory /usr/libexec/git-core>
248 15 Gregory Bartholomew
   <Files "git-http-backend">
249 15 Gregory Bartholomew
      Options +ExecCGI
250 13 Gregory Bartholomew
   </Files>
251 13 Gregory Bartholomew
</Directory>
252 13 Gregory Bartholomew
253 13 Gregory Bartholomew
<Location /git>
254 13 Gregory Bartholomew
   AuthType Basic
255 13 Gregory Bartholomew
   AuthName "CAMPUS"
256 13 Gregory Bartholomew
   AuthBasicProvider external
257 13 Gregory Bartholomew
   AuthExternal pwauth
258 13 Gregory Bartholomew
   Require valid-user
259 13 Gregory Bartholomew
260 13 Gregory Bartholomew
   PerlAccessHandler Apache::Authn::Redmine::access_handler
261 13 Gregory Bartholomew
   PerlAuthenHandler Apache::Authn::Redmine::authen_handler
262 13 Gregory Bartholomew
 
263 13 Gregory Bartholomew
   RedmineDSN "DBI:mysql:database=redmine;host=localhost" 
264 14 Gregory Bartholomew
   RedmineDbUser "redmine" 
265 13 Gregory Bartholomew
   # RedmineDbPass "password"
266 13 Gregory Bartholomew
   RedmineGitSmartHttp yes
267 13 Gregory Bartholomew
</Location>
268 13 Gregory Bartholomew
269 13 Gregory Bartholomew
Alias /git-private /git-1/repositories
270 13 Gregory Bartholomew
271 13 Gregory Bartholomew
<Location /git-private>
272 13 Gregory Bartholomew
   Order deny,allow
273 13 Gregory Bartholomew
   Deny from all
274 13 Gregory Bartholomew
   <Limit GET PROPFIND OPTIONS REPORT>
275 13 Gregory Bartholomew
      Options Indexes FollowSymLinks MultiViews
276 13 Gregory Bartholomew
      Allow from 127.0.0.1
277 13 Gregory Bartholomew
      Allow from localhost
278 13 Gregory Bartholomew
   </Limit>
279 13 Gregory Bartholomew
</Location>
280 13 Gregory Bartholomew
281 13 Gregory Bartholomew
<Directory "/var/www/redmine/public">
282 13 Gregory Bartholomew
   RailsEnv production
283 13 Gregory Bartholomew
   RailsBaseURI /
284 13 Gregory Bartholomew
285 13 Gregory Bartholomew
   Options -MultiViews
286 13 Gregory Bartholomew
   AllowOverride All
287 13 Gregory Bartholomew
</Directory></code></pre>
288 13 Gregory Bartholomew
289 13 Gregory Bartholomew
In conf/ssl.conf:
290 13 Gregory Bartholomew
291 13 Gregory Bartholomew
<pre><code class="apache">LogLevel warn
292 13 Gregory Bartholomew
SSLEngine on
293 13 Gregory Bartholomew
SSLProtocol all -SSLv2
294 13 Gregory Bartholomew
SSLCipherSuite RC4-SHA:AES128-SHA:ALL:!ADH:!EXP:!LOW:!MD5:!SSLV2:!NULL
295 13 Gregory Bartholomew
SSLCertificateFile /etc/pki/tls/certs/your-server.crt
296 13 Gregory Bartholomew
SSLCertificateKeyFile /etc/pki/tls/private/your-server.key
297 13 Gregory Bartholomew
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
298 13 Gregory Bartholomew
SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
299 13 Gregory Bartholomew
300 13 Gregory Bartholomew
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
301 13 Gregory Bartholomew
    SSLOptions +StdEnvVars
302 13 Gregory Bartholomew
</Files>
303 13 Gregory Bartholomew
<Directory "/var/www/cgi-bin">
304 13 Gregory Bartholomew
    SSLOptions +StdEnvVars
305 13 Gregory Bartholomew
</Directory>
306 13 Gregory Bartholomew
307 13 Gregory Bartholomew
SetEnvIf User-Agent ".*MSIE.*" \
308 13 Gregory Bartholomew
         nokeepalive ssl-unclean-shutdown \
309 13 Gregory Bartholomew
         downgrade-1.0 force-response-1.0
310 13 Gregory Bartholomew
</code></pre>
311 13 Gregory Bartholomew
312 13 Gregory Bartholomew
In conf.d/ssl.conf:
313 13 Gregory Bartholomew
314 13 Gregory Bartholomew
<pre><code class="apache">LoadModule ssl_module modules/mod_ssl.so
315 1 Felix Schäfer
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
316 1 Felix Schäfer
SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)
317 1 Felix Schäfer
SSLSessionCacheTimeout  300
318 13 Gregory Bartholomew
SSLMutex default
319 13 Gregory Bartholomew
SSLRandomSeed startup file:/dev/urandom  256
320 13 Gregory Bartholomew
SSLRandomSeed connect builtin
321 13 Gregory Bartholomew
SSLCryptoDevice builtin
322 13 Gregory Bartholomew
</code></pre>
323 17 Mr. DTTH
324 17 Mr. DTTH
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.  
325 17 Mr. DTTH
326 13 Gregory Bartholomew
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.
327 15 Gregory Bartholomew
328 13 Gregory Bartholomew
yum -y install gcc make perl-LDAP perl-Authen-Simple
329 13 Gregory Bartholomew
cpan
330 1 Felix Schäfer
cpan> install Authen::Simple::LDAP