Install Gitorious on OS X 10.6 (Snow Leopard)

Requirements

We will be compiling some items directly. These items will be downloaded into a directory called source which we will create inside our home directory.

cd ~/
mkdir source

___ DONE

PATH Environment Variable

On a clean install of OS X 10.6 you will need to create the following directory:

sudo mkdir -p /usr/local/bin

and then add it to your PATH environment variable

PATH=$PATH:/usr/local/bin

___ DONE

Setup Built in Apache2 Web Server

Create the following directories:

sudo mkdir /etc/apache2/sites-enabled/
sudo mkdir /etc/apache2/mods-enabled/
sudo mkdir /Library/WebServer/cgi-bin
sudo mkdir /Library/WebServer/www.bluequartz.net
sudo mkdir /Library/WebServer/gitserver.bluequartz.net

Add the following lines to the bottom of the /etc/apache2/httpd.conf file:

NameVirtualHost *:80

# Include module configuration:
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf

Include /etc/apache2/sites-enabled/default
Include /etc/apache2/sites-enabled/gitorious
Include /etc/apache2/sites-enabled/gitorious-ssl

Next find the following line in the /etc/httpd.conf file:
DocumentRoot "/Library/WebServer/Documents"
and add a # to the front of the line of code in order to comment it out. Find the line
ServerName www.example.com:80
and comment that out. Find the section starting with

<Directory "/Library/WebServer/Documents">

and comment out everything down to the next

</Directory>

Also comment out the following section:

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
</Directory>

___ DONE

Configure the Default Web Site

We now need to configure the default web site to look in /Library/WebServer/www.bluequartz.net for our 'normal' corporate web site. If your business is large enough you would probably want 2 different servers but since we are small we use a single server for everything. If you are ONLY going to run gitorious on this server then you can skip this subsection and go to the section on configuring XSendFile. Edit the /etc/apache2/sites-enabled/default

sudo emacs /etc/apache2/sites-enabled/default

and fill with this content:

<VirtualHost *:80>
  ServerAdmin mike.jackson@bluequartz.net
  ServerName  www2.bluequartz.net
  DocumentRoot /Library/WebServer/www.bluequartz.net
  <Directory />
       Options FollowSymLinks
       AllowOverride None
  </Directory>
  <Directory /Library/WebServer/>
         Options  FollowSymLinks MultiViews
       AllowOverride None
       Order allow,deny
       allow from all
  </Directory>
  ScriptAlias /cgi-bin/ /Library/WebServer/cgi-bin/
  <Directory "/Library/WebServer/cgi-bin">
         AllowOverride None
       Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
       Order allow,deny
       Allow from all
  </Directory>
  # This is to password protect the upload page
  <Directory "/Library/WebServer/www.bluequartz.net/upload" >
  AuthType Digest
  AuthName "Upload"
  AuthDigestDomain /upload/ http://www.bluequartz.net/upload/
  AuthUserFile  "/etc/apache2/passwords"
  Require valid-user
  BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On
  </Directory>

  # Possible values include: debug, info, notice, warn, error, crit,
  # alert, emerg.
  LogLevel warn

  #
  # The following directives define some format nicknames for use with
  # a CustomLog directive (see below).
  #
  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
  LogFormat "%h %l %u %t \"%r\" %>s %b" common
  LogFormat "%{Referer}i -> %U" referer
  LogFormat "%{User-agent}i" agent

  CustomLog /var/log/apache2/www_access.log combined
  TransferLog /var/log/apache2/www_access.log
  ErrorLog /var/log/apache2/www_error.log

  Alias /doc/ "/usr/share/doc/"
  <Directory "/usr/share/doc/">
      Options Indexes MultiViews FollowSymLinks
      AllowOverride None
      Order deny,allow
      Deny from all
      Allow from 127.0.0.0/255.0.0.0 ::1/128
  </Directory>
</VirtualHost>

___ DONE

XSendFile

OS X does not come standard with XSendFile support so we need to compile and install it. The following shell commands will download the latest version, compile and install it into the appropriate location in the filesystem.

cd ~
mkdir source
cd source
mkdir xsendfile
cd xsendfile
curl "http://tn123.ath.cx/mod_xsendfile/mod_xsendfile.c" -o mod_xsendfile.c
sudo apxs -cia -Wc,"-arch x86_64" -Wl,"-arch x86_64" mod_xsendfile.c

Use emacs (or another text editor) to create the following file /etc/apache2/mods-enabled/xsendfile.load that contains the following line:

LoadModule xsendfile_module libexec/apache2/mod_xsendfile.so

___ DONE

Setup SSL for Apache

By defaul SSL is NOT enabled for Apache2 under OS X. We can enable it by adding some more files to the /etc/apache2/mods-enabled directory with SSL specific settings. Note that I already have both my certificate file and certificate key. If you need do not have these SSL certificate files then you will need to generate those files.

Use a text editor to create /etc/apache2/mods-enabled/ssl.conf

#
# This is the Apache server configuration file providing SSL support.
# It contains the configuration directives to instruct the server how to
# serve pages over an https connection. For detailing information about these
# directives see <URL:http://httpd.apache.org/docs/2.2/mod/mod_ssl.html>
#
# Do NOT simply read the instructions in here without understanding
# what they do.  They're here only as hints or reminders.  If you are unsure
# consult the online docs. You have been warned.
#
<IfModule mod_ssl.c>
  #
  # When we also provide SSL we have to listen to the
  # standard HTTP port (see above) and to the HTTPS port
  #
  # Note: Configurations that use IPv6 but not IPv4-mapped addresses need two
  #       Listen directives: "Listen [::]:443" and "Listen 0.0.0.0:443"
  #
  Listen 443

  ##
  ##  SSL Global Context
  ##
  ##  All SSL configuration in this context applies both to
  ##  the main server and all SSL-enabled virtual hosts.
  ##

  #
  #   Some MIME-types for downloading Certificates and CRLs
  #
  AddType application/x-x509-ca-cert .crt
  AddType application/x-pkcs7-crl    .crl

  #   Pass Phrase Dialog:
  #   Configure the pass phrase gathering process.
  #   The filtering dialog program (`builtin' is a internal
  #   terminal dialog) has to provide the pass phrase on stdout.
  SSLPassPhraseDialog  builtin

  #   Inter-Process Session Cache:
  #   Configure the SSL Session Cache: First the mechanism
  #   to use and second the expiring timeout (in seconds).
  #SSLSessionCache         "dbm:/private/var/run/ssl_scache"
  SSLSessionCache        "shmcb:/private/var/run/ssl_scache(512000)"
  SSLSessionCacheTimeout  300

  #   Semaphore:
  #   Configure the path to the mutual exclusion semaphore the
  #   SSL engine uses internally for inter-process synchronization.
  SSLMutex  "file:/private/var/run/ssl_mutex"

  # enable only secure protocols: SSLv3 and TLSv1, but not SSLv2
  SSLProtocol all -SSLv2
</IfModule>

___ DONE

Create /etc/apache2/sites-enabled/gitorious

Create /etc/apache2/sites-enabled/gitorious file that contains configuration information about where to find a particular site. The assumption is that you have full control over your server, web server and web server configuration. We are going to create a few "Virtual Hosts" on the Web server. One to serve our normal static web site at www.bluequartz.net and another to serve the gitorious web site at gitorious.bluequartz.net.

sudo emacs /etc/apache2/sites-enabled/gitorious
#Edit with the following content
<VirtualHost *:80>
  ServerName gitserver.bluequartz.net
  DocumentRoot /Library/WebServer/gitserver.bluequartz.net/gitorious/public

  # Enable X-SendFile for gitorious repo archiving to work
  XSendFile on
  XSendFileAllowAbove on

  # Possible values include: debug, info, notice, warn, error, crit,
  # alert, emerg.
  LogLevel warn
  #
  # The following directives define some format nicknames for use with
  # a CustomLog directive (see below).
  #
  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
  LogFormat "%h %l %u %t \"%r\" %>s %b" common
  LogFormat "%{Referer}i -> %U" referer
  LogFormat "%{User-agent}i" agent

  CustomLog /var/log/apache2/gitserver_access.log combined
  TransferLog /var/log/apache2/gitserver_access.log
  ErrorLog /var/log/apache2/gitserver_error.log
</VirtualHost>

___ DONE

Create /etc/apache2/sites-enabled/gitorious-ssl

Create /etc/apache2/sites-enabled/gitorious-ssl file which configures the SSL certificates and other SSL related options for the gitorious.bluequartz.net site.

sudo emacs /etc/apache2/sites-enabled/gitorious-ssl
# Edit with the following content
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
  SSLEngine on
  SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
  SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
  BrowserMatch ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
  DocumentRoot /Library/WebServer/gitorious.bluequartz.net/gitorious/public

  # Possible values include: debug, info, notice, warn, error, crit,
  # alert, emerg.
  LogLevel warn
  #
  # The following directives define some format nicknames for use with
  # a CustomLog directive (see below).
  #
  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
  LogFormat "%h %l %u %t \"%r\" %>s %b" common
  LogFormat "%{Referer}i -> %U" referer
  LogFormat "%{User-agent}i" agent

  CustomLog /var/log/apache2/gitorious_ssl_access.log combined
  TransferLog /var/log/apache2/gitorious_ssl_access.log
  ErrorLog /var/log/apache2/gitorious_ssl_error.log

SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
<FilesMatch "\.(cgi|shtml|phtml|php)$">
    SSLOptions +StdEnvVars
</FilesMatch>
<Directory "/Library/WebServer/CGI-Executables">
    SSLOptions +StdEnvVars
</Directory>
</VirtualHost>
</IfModule>

___ DONE

Install Git

One needs to install "Git" onto the system. Download and compile git from source and install it into /usr/local/git. Append your PATH environment variable to include

PATH=$PATH:/usr/local/git/bin

cd ~
mkdir source
cd source
curl "http://kernel.org/pub/software/scm/git/git-1.7.2.1.tar.gz" -o git-1.7.2.1.tar.gz
tar -xvzf git-1.7.2.1.tar.gz
cd git-1.7.2.1
./configure --prefix=/usr/local/git
make
sudo make install

___ DONE

ImageMagick Setup and Installation

You will need to download and install ImageMagick. Download the source files from ftp.imagemagick.org/pub/ImageMagick/ImageMagick.tar.gz into the source directory. After that you can run the following shell commands to compile and install it into /usr/local/imagemagick. Append your PATH environment variable to include

PATH=$PATH:/usr/local/imagemagick/bin

cd ~/source
tar -xvzf ImageMagick.tar.gz
cd ImageMagick-6.6.3-1/
./configure --prefix=/usr/local/imagemagick
make
sudo make install

___ DONE

Install MySQL

Use a web browser to navigate to http://dev.mysql.com/downloads/mysql/ and download and compile the sources yourself. Download the source package from http://dev.mysql.com/downloads/mysql/#downloads and install into /usr/local/mysql. Append your PATH environment variable to include

PATH=$PATH:/usr/local/mysql/bin

cd source
tar -zvzf mysql-5.1.49.tar.gz
cd mysql-5.1.49
./configure --prefix=/usr/local/mysql --with-extra-charsets=complex \
--enable-thread-safe-client --enable-local-infile --enable-shared
make
sudo make install
cd /usr/local/mysql
sudo ./bin/mysql_install_db --user=_mysql
sudo chown -R _mysql ./var
cd ..

We now need to get MySQL to auto start during boot time. To do this use the following plist file that you create in /Library/LaunchDaemons

sudo emacs /Library/LaunchDaemons/com.mysql.mysqld.plist

and place the following content into the file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>com.mysql.mysqld</string>
    <key>Program</key>
    <string>/usr/local/mysql/bin/mysqld_safe</string>
    <key>RunAtLoad</key>
    <true/>
    <key>UserName</key>
    <string>_mysql</string>
    <key>WorkingDirectory</key>
    <string>/usr/local/mysql</string>
</dict>
</plist>

After you save and close the file run the following commands to change the owner of the file and start up the mysql daemon.

sudo chown root /Library/LaunchDaemons/com.mysql.mysqld.plist
sudo launchctl load /Library/LaunchDaemons/com.mysql.mysqld.plist

You can also stop the mysql daemon by running the following command

sudo launchctl unload /Library/LaunchDaemons/com.mysql.mysqld.plist

We need to set the MySQL Root password in order to better secure our databases for production use in addition to letting mysql remove some test database files.

/usr/local/mysql/bin/mysqladmin -u root password 'XXXXXXXX'
/usr/local/mysql/bin/mysqladmin -u root -h gitserver.bluequartz.net password 'XXXXXXXX'
sudo /usr/local/mysql/bin/mysql_secure_installation

PASSWORD USED: ______________
___ DONE

UltraSphinx Install

Use the following directions to compile and install the UltraSphinx Search facilities. Compile and install it into /usr/local/imagemagick. Append your PATH environment variable to include

PATH=$PATH:/usr/local/sphinx/bin


@verbatim
cd ~/
mkdir source
cd source
curl "http://sphinxsearch.com/downloads/sphinx-0.9.8.1.tar.gz" -o
tar -xvzf sphinx-0.9.8.1.tar.gz
cd sphinx-0.9.8.1/
./configure --prefix=/usr/local/sphinx --with-mysql-includes=/usr/local/mysql/include/mysql \
   --with-mysql-libs=/usr/local/mysql/lib/mysql
make all
sudo make install

___ DONE

Create Memcached LaunchDaemon PList File

OS X 10.6 comes preinstalled with memcached but does not launch it at system startup. We will create a LaunchDaemon plist file that will launch memcached when the machine is booted.

sudo touch /Library/LaunchDaemons/com.gitorious.memcached.plist
sudo emacs /Library/LaunchDaemons/com.gitorious.memcached.plist

Place the following into the /Library/LaunchDaemons/com.gitorious.memcached.plist file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>com.gitorious.memcached</string>
	<key>Program</key>
	<string>/usr/bin/memcached</string>
	<key>ProgramArguments</key>
	<array>
	  <string>memcached</string>
  	<string>-l</string>
  	<string>127.0.0.1</string>
  	<string>-p</string>
  	<string>11211</string>
  	<string>-m</string>
  	<string>64</string>
  </array>
	<key>RunAtLoad</key>
	<true/>
	<key>KeepAlive</key>
	<true/>
	<key>UserName</key>
	<string>nobody</string>
</dict>
</plist>

___ DONE

Install Ruby Gems

BEFORE proceeding with this section MAKE SURE mysql is on your PATH environment. You should be able to execute which mysql and be returned the proper path to the mysql executable.

[user@server] $ which mysql
/usr/local/mysql/bin/mysql

IF you do NOT a return then you need to add /usr/local/mysql/bin to your PATH like the following:

PATH=$PATH:/usr/local/mysql/bin

which will make the proper mysql variables and executables available when the gems are installed.

PATH=$PATH:/usr/local/mysql/bin:/usr/local/imagemagick/bin
sudo env ARCHFLAGS="-arch x86_64" gem install -b --no-ri --no-rdoc rmagick chronic geoip daemons hoe echoe \
   ruby-yadis ruby-openid mime-types diff-lcs json rack ruby-hmac rake \
   stompserver passenger rails mysql
sudo env ARCHFLAGS="-arch x86_64" gem install -b --no-ri --no-rdoc -v 1.3.1.1 rdiscount
sudo env ARCHFLAGS="-arch x86_64" gem install -b --no-ri --no-rdoc -v 1.1 stomp

sudo ln -s /Library/Ruby/Gems/1.8/gems/rake-0.8.7/bin/rake /usr/local/bin
sudo ln -s /Library/Ruby/Gems/1.8/gems/stompserver-0.9.9/bin/stompserver /usr/local/bin

___ DONE

Install Passenger

Install the Passenger Ruby on Rails Deployment stack

sudo /Library/Ruby/Gems/1.8/gems/passenger-2.2.15/bin/passenger-install-apache2-module

___ DONE

Create /etc/apache2/mods-available/passenger.load

Create the /etc/apache2/mods-available/passenger.load file with the following configuration. This same information is also printed out by the last command so make sure it matches.

sudo emacs /etc/apache2/mods-enabled/passenger.load

And place the following content in that file.

LoadModule passenger_module /Library/Ruby/Gems/1.8/gems/passenger-2.2.15/ext/apache2/mod_passenger.so
PassengerRoot /Library/Ruby/Gems/1.8/gems/passenger-2.2.15
PassengerRuby /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby

___ DONE

Create the Git System User

Create a shell script using a text editor and the execute the script by changing the permissions on the file to be executable chmod ug+x createuser.sh.

cd ~/source
touch createuser.sh
chmod ug+x createuser.sh
emacs createuser.sh
#!/bin/bash
# Get a Group ID value to be used when creating the 'git' group
groupmaxid=$(dscl . -list /Groups PrimaryGroupID | awk '{print $2}' | sort -ug | tail -1)
groupnumber=$((groupmaxid+1))

#Create the Group 'git'
echo "Creating Group 'git' with group id = $groupnumber"
sudo dscl . -create /Groups/git PrimaryGroupID $groupnumber

# Get a user ID value to be used when creating the 'git' user
maxid=$(dscl . -list /Users UniqueID | awk '{print $2}' | sort -ug | tail -1)
usernumber=$((maxid+1))
username=git

echo "Creating a 'git' user with id = $usernumber"
dscl . -create /Users/$username
dscl . -create /Users/$username UserShell /bin/bash
dscl . -create /Users/$username RealName $username
dscl . -create /Users/$username UniqueID $usernumber
dscl . -create /Users/$username NFSHomeDirectory /Users/$username
# Replace with a real password
dscl . -passwd /Users/$username rb21h45*
dscl . -create /Users/$username PrimaryGroupID $username

# Create the user's home directory plus the .ssh directory
mkdir -p /Users/$username/.ssh
chmod 0700 /Users/$username/.ssh
touch /Users/$username/.ssh/authorized_keys
chmod 700 /Users/$username/.ssh
chmod 600 /Users/$username/.ssh/authorized_keys
mkdir /Users/$username/repositories
mkdir /Users/$username/tarballs
mkdir /Users/$username/tarballs-work

# create the .bashrc to add git to their path
echo "PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin" > /Users/$username/.bashrc
echo "GIT_INSTALL=/usr/local/git" >> /Users/$username/.bashrc
echo "MYSQL_INSTALL=/usr/local/mysql" >> /Users/$username/.bashrc
echo "IMAGEMAGICK_INSTALL=/usr/local/imagemagick" >> /Users/$username/.bashrc
echo "SPHINX_INSTALL=/usr/local/sphinx" >> /Users/$username/.bashrc
echo "PATH=$PATH:$GIT_INSTALL/bin" >> /Users/$username/.bashrc
echo "PATH=$PATH:$GITORIOUS_ROOT/script" >> /Users/$username/.bashrc
echo "PATH=$PATH:$MYSQL_INSTALL/bin" >> /Users/$username/.bashrc
echo "PATH=$PATH:$SPHINX_INSTALL/bin" >> /Users/$username/.bashrc
echo "PATH=$PATH:$IMAGEMAGICK_INSTALL/bin" >> /Users/$username/.bashrc

#Make sure the permissions are set correctly
chmod ug+rw /Users/$username/.bashrc

# Change ownership of the users directory to their username
chown -R $username:git /Users/$username

# We need to add the _www user as a member of the 'git' group
echo "Adding '_www' as a member of the 'git' group."
dscl . append /Groups/git GroupMembership _www

___ DONE

Download Gitorious Source Code

We are going to fetch the Gitorious project from the http://www.gitorious.com site and configure it as our system admin user. After we have completed all of the configuration we are going to change all the permissions over to the a user called 'git' which will be the userid that will actually be running the applications. We are going to clone the gitorious project into the /Library/WebServer/gitserver.bluequartz.net/gitorious because that is where all the defaults have us looking for it.

sudo mkdir -p /Library/WebServer/gitserver.bluequartz.net
sudo chmod ug+rwx /Library/WebServer/gitserver.bluequartz.net
su git
cd /Library/WebServer/gitserver.bluequartz.net/
git clone git://gitorious.org/gitorious/mainline.git gitorious

___ DONE

Configure Gitorious

We are now going to start configuring the actual Gitorious Ruby-on-Rails application settings and environment. First we need to copy some sample config files so that gitorious reads the configuration from those files.

su git
cd /Library/WebServer/gitserver.bluequartz.net/gitorious
mkdir tmp/pids
cp config/database.sample.yml config/database.yml
cp config/gitorious.sample.yml config/gitorious.yml
cp config/broker.yml.example config/broker.yml

___ DONE

Edit config/gitorious.yml

Edit the /Library/WebServer/gitserver.bluequartz.net/gitorious/config/gitorious.yml file to have the following contents. Note the "\" character in the cookie_secret key. You need to make sure the value is on a single complete line. This usually involves deleting the hard carriage returns and the '\' character in the value.

# Be sure if you paste a generated secret key using apg -m 64 that you clean up
# any line breaks. The secret key that is pasted should be on a SINGLE line.
production:

  # The session secret key (`apg -m 64` is always useful for this kinda stuff)
  cookie_secret: urbecpajicEvpigdiOlqueDracpevyerbEmDecetsendeehurEjShucJox8Ojit4WaWrinyienderdalyai\
  fugNeahatdashyunnamFucwerdolfyedyeactEjEajIb5IksEytkurewsEetAiwirtEkfedtheebyatNoga\
  nyoofBabikOcyemEshvovHasojTropsyengyegidzyggEdamCasdijHegdeasfudCovmenpobdywajcycsuch\
  Dabr2NadUlHighEisyoilmojliawgOdAcyimpifCaiWumtangEvzueshjajOtFuciddEbWhoivedesjetockV\
  emOdEvnooquoncoapCaQuavnelkoijfudcatfezUlreylbUd

  # The path where git repositories are stored. The actual (bare) repositories resides
  # in repository_base_path/#{project.slug}/#{repository.name}.git/:
  repository_base_path: "/Users/git/repositories"

  # Stuff that's in the html <head>. custom stats javascript code etc
  extra_html_head_data:

  # System message that will appear on all pages if present
  system_message:

  # Port the ./script/gitorious script should use which should be
  # the same port that the web server is running on. In Some development
  # environments you may see 3000 for the value. For production
  # servers you should use the same port as your web server.
  gitorious_client_port: 80

  # Host the ./script/gitorious script should use:
  gitorious_client_host: gitserver.bluequartz.net

  # Host which is serving the gitorious app, eg "gitorious.org"
  gitorious_host: gitserver.bluequartz.net

  # System User which is running git daemon
  gitorious_user: git

  # Email spam on server errors to:
  # You probably want this during development or when you are trying to debug
  # an installation that is not working correctly.
  exception_notification_emails: mike.jackson@bluequartz.net

  # Mangle visible e-mail addresses (spam protection)
  mangle_email_addresses: true

  # Enable or Disable Public Mode (true) or Private Mode (false)
  public_mode: true

  # Define your locale
  locale: en

  # Where should we store generated tarballs?
  # (should be readable by webserver, since we tell it to send the file using X-Sendfile)
  archive_cache_dir: "/Users/git/tarballs"

  # Which directory should we work in when we generate tarballs, before moving
  # them to the above dir?
  archive_work_dir: "/Users/git/tarballs-work"

  # is it only site admins who can create new projects?
  only_site_admins_can_create_projects: false

  # Should we hide HTTP clone urls?
  hide_http_clone_urls: false

  # Is this gitorious.org? Read: should we have a very flashy homepage?
  is_gitorious_dot_org: false

  # Pick a default license
  #default_license: GNU Affero General Public License (AGPLv3)

___ DONE

Edit config/database.yml

Edit the file /Library/WebServer/gitserver.bluequartz.net/gitorious/config/database.yml.

# Remove every section but production
# Make sure the 'production' section is the following
 production:
   adapter: mysql
   database: gitorious
   username: git
   password: XXXXXXXX
   host: localhost
   encoding: utf8
   socket:

PASSWORD USED: ____________
___ DONE

Create SQL User

Run the following as the 'git' system user replacing "XXXXXXXXXX" with the proper mysql root password that was set earlier in this guide.

su git
mysql -uroot -p
Enter password: XXXXXXXXXX
Welcome to the MySQL monitor.  Commands end with ; or \g.
mysql> CREATE USER 'git'@'localhost' IDENTIFIED BY  'XXXXXXXXXX';

mysql> GRANT ALL PRIVILEGES ON * . * TO  'git'@'localhost' IDENTIFIED BY  'XXXXXXXXXX' \
   WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 \
   MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;

mysql> GRANT ALL PRIVILEGES ON  `gitorious` . * TO  'git'@'localhost';
mysql> quit

___ DONE

Create the Gitorious Databases

These next commands will create the MySQL databases and then migrate them to the production environment. Configure the ruby scripts to work with your mysql configuration (mind your environment settings!):

su git
cd /Library/WebServer/gitserver.bluequartz.net/gitorious
rake db:create RAILS_ENV=production
rake db:migrate RAILS_ENV=production

___ DONE

Create the Gitorious Admin User

Create the admin user of the gitorious installation on the gitorious console (which is just a front for the mysql console).

su git
cd /Library/WebServer/gitserver.bluequartz.net/gitorious
env RAILS_ENV=production /usr/bin/ruby script/create_admin
 Type in Administrator's e-mail:
 gitorious-admin@bluequartz.net
 Type in Administrator's password:
 XXXXXXXXXXXX
 Admin user created successfully.

PASSWORD USED: ____________
___ DONE

Configure Sphinx Search Daemon

The database is now more or less set up. It is time to configure the sphinx search daemon. Edit gitorious/config/ultrasphinx/default.base and replace 0.0.0.0 with localhost.

su git
cd /Library/WebServer/gitserver.bluequartz.net/gitorious/config/ultrasphinx/
emacs default.base

Next load these configurations into the ruby files

su git
cd /Library/WebServer/gitserver.bluequartz.net/gitorious
rake ultrasphinx:bootstrap RAILS_ENV=production

Set the permissions again, just to make sure:

# Login as an admin user or user with 'sudo' priviledges.
cd /Library/WebServer/gitserver.bluequartz.net/gitorious
sudo chown -R git:git config/environment.rb script/poller log tmp
sudo chmod -R g+w config/environment.rb script/poller log tmp
sudo chmod ug+x script/poller

___ DONE

Create LaunchDaemon for git-daemon script

Create the git-daemon script in gitorious/launchd/git-daemon.sh

mkdir /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/
touch /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-daemon.sh
chmod u+x /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-daemon.sh
emacs /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-daemon.sh

Edit the /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-daemon.sh file to have the following content:

#! /bin/sh
# This script is designed to be used with OS X LaunchDaemon process. Read
# more about LaunchDaemon at http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/BPSystemStartup.html

# Author: Fabio Akita <fabioakita@gmail.com>
# converted to LaunchDaemon by
# Author: mike jackson (mike.jackson@bluequartz.net)
#
RETVAL=0
PROG="git-daemon"
GITORIOUS_ROOT=/Library/WebServer/gitserver.bluequartz.net/gitorious
GIT_DAEMON="$GITORIOUS_ROOT/script/git-daemon"
GIT_DAEMON_LOCK_FILE=$GITORIOUS_ROOT/tmp/git-daemon.lock
GIT_DAEMON_PID_FILE=$GITORIOUS_ROOT/tmp/pids/git-daemon.pid
GIT_DAEMON_LOG_FILE=$GITORIOUS_ROOT/log/git-daemon_launchdaemon.log
GITORIOUS_PRODUCTION_LOG=$GITORIOUS_ROOT/log/production.log
RUNNING=0

PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
GIT_INSTALL=/usr/local/git
MYSQL_INSTALL=/usr/local/mysql
IMAGEMAGICK_INSTALL=/usr/local/imagemagick
SPHINX_INSTALL=/usr/local/sphinx

PATH=$PATH:$GIT_INSTALL/bin
PATH=$PATH:$GITORIOUS_ROOT/script
PATH=$PATH:$MYSQL_INSTALL/bin
PATH=$PATH:$SPHINX_INSTALL/bin
PATH=$PATH:$IMAGEMAGICK_INSTALL/bin

# Check to make sure logs files exist
if [ ! -f $GIT_DAEMON_LOG_FILE ]; then
  touch "$GIT_DAEMON_LOG_FILE"
fi
if [ ! -f $GITORIOUS_PRODUCTION_LOG ]; then
  touch "$GITORIOUS_PRODUCTION_LOG"
fi
#---------------------------------------
start_git_daemon()
{
    echo `date` " - Starting $PROG " >> $GIT_DAEMON_LOG_FILE
    touch $GIT_DAEMON_LOCK_FILE
    # Start the Git-Daemon Process
    /usr/bin/ruby "$GIT_DAEMON"
}
#---------------------------------------
# stop will get called when Launchd sends a SIGTERM signal to the git-daemon
# process so we don't need a lot of the clean up stuff that was in there
stop_git_daemon()
{
  echo  `date` " - $PROG: Caught Signal and cleaning pid and lock files"  >> $GIT_DAEMON_LOG_FILE
  [ "$RETVAL" = 0 ] && rm -f $GIT_DAEMON_LOCK_FILE && rm -f $GIT_DAEMON_PID_FILE
  # Kill the ultrasphinx process also
  $GITORIOUS_ROOT/launchd/git-ultrasphinx.sh stop
  $GITORIOUS_ROOT/launchd/git-poller.sh stop
  echo
}
#---------------------------------------
# setup the signal catcher
trap "{ stop_git_daemon; exit 1; }" EXIT

case "$1" in
  start)
    # we are going to get the git-ultrasphinx daemon running here because it does
    # not block when the script is run which makes it impossible to run it from
    # a launchd process as launchd will keep respawning the ultrasphinx process
    # thinking it is dead because it completes so quickly
    echo  `date` " - Starting UltraSphinx...."  >> $GIT_DAEMON_LOG_FILE
    $GITORIOUS_ROOT/launchd/git-ultrasphinx.sh start
    $GITORIOUS_ROOT/launchd/git-poller.sh start
    start_git_daemon
    ;;
  *)
    echo $"Usage: $0 {start}"
    RETVAL=1
esac

Now we need to create a plist file at /Library/LaunchDaemons so that the git-daemon process is started up using Launchctl during boot up.

sudo emacs /Library/LaunchDaemons/com.gitorious.git-daemon.plist

and place the following content in this file. If you are running gitorious from a different location on the filesystem then make the appropriate adjustments to the paths:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.gitorious.git-daemon</string>
  <key>ProgramArguments</key>
  <array>
  <string>/Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-daemon.sh</string>
   <string>start</string>
  </array>
  <key>UserName</key>
  <string>git</string>
  <key>RunAtLoad</key>
  <true/>
  <key>OnDemand</key>
  <false/>
</dict>
</plist>

___ DONE

Create LaunchDaemon for git-ultrasphinx Script

Create the git-daemon script in gitorious/launchd/git-ultrasphinx.sh

mkdir /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/
touch /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-ultrasphinx.sh
chmod u+x /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-ultrasphinx.sh
emacs /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-ultrasphinx.sh

Edit the /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-ultrasphinx.sh file to have the following content:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          Gitorious Ultrasphinx
# Required-Start:
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Ultrasphinx daemon
# Description:       Starts the Ultrasphinx daemons needed by Gitorious
### END INIT INFO

# Author: Fabio Akita <fabioakita@gmail.com>
# Author: Fabio Akita <fabioakita@gmail.com>
# converted to LaunchDaemon by
# Author: mike jackson (mike.jackson@bluequartz.net)
#

RETVAL=0
GITORIOUS_ROOT=/Library/WebServer/gitserver.bluequartz.net/gitorious
START_CMD="cd $GITORIOUS_ROOT && rake ultrasphinx:daemon:start RAILS_ENV=production"
STOP_CMD="cd $GITORIOUS_ROOT && rake ultrasphinx:daemon:stop RAILS_ENV=production"
RESTART_CMD="cd $GITORIOUS_ROOT && rake ultrasphinx:daemon:restart RAILS_ENV=production"
STATUS_CMD="cd $GITORIOUS_ROOT && rake ultrasphinx:daemon:status RAILS_ENV=production"
ULTRA_SPHINX_LOCK_FILE=$GITORIOUS_ROOT/tmp/git-ultrasphinx.lock
ULTRA_SPHINX_PID_FILE=$GITORIOUS_ROOT/tmp/pids/searchd.pid
ULTRA_SPHINX_LOG_FILE=$GITORIOUS_ROOT/log/git-ultrasphinx_launchdaemon.log

PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
GIT_INSTALL=/usr/local/git
MYSQL_INSTALL=/usr/local/mysql
IMAGEMAGICK_INSTALL=/usr/local/imagemagick
SPHINX_INSTALL=/usr/local/sphinx

PATH=$PATH:$GIT_INSTALL/bin
PATH=$PATH:$GITORIOUS_ROOT/script
PATH=$PATH:$MYSQL_INSTALL/bin
PATH=$PATH:$SPHINX_INSTALL/bin
PATH=$PATH:$IMAGEMAGICK_INSTALL/bin

# Check to make sure logs files exist
if [ ! -f $ULTRA_SPHINX_LOG_FILE ]; then
  touch "$ULTRA_SPHINX_LOG_FILE"
fi

case "$1" in
  start)
    echo `date` " Starting git-ultrasphinx" >> "$ULTRA_SPHINX_LOG_FILE"
    cd $GITORIOUS_ROOT && rake ultrasphinx:daemon:start RAILS_ENV=production
    ;;
  stop)
    echo `date` " Stopping git-ultrasphinx" >> "$ULTRA_SPHINX_LOG_FILE"
    cd $GITORIOUS_ROOT && rake ultrasphinx:daemon:stop RAILS_ENV=production
    ;;
  restart)
    echo `date` " Re-Starting git-ultrasphinx" >> "$ULTRA_SPHINX_LOG_FILE"
    cd $GITORIOUS_ROOT && rake ultrasphinx:daemon:restart RAILS_ENV=production
    ;;
  status)
    echo `date` " Status For  git-ultrasphinx" >> "$ULTRA_SPHINX_LOG_FILE"
    cd $GITORIOUS_ROOT && rake ultrasphinx:daemon:status RAILS_ENV=production
    ;;
  *)
    echo $"Usage: $0 {start|status}"
    RETVAL=1
esac

echo `date` " git-ultrasphinx.sh script complete with argument '$1' " >> "$ULTRA_SPHINX_LOG_FILE"

___ DONE

Create git-poller Init Script

Create the git-poller script in gitorious/launchd/git-poller.sh

mkdir /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/
touch /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-poller.sh
chmod u+x /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-poller.sh
emacs /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-poller.sh

edit the /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/git-poller.sh to have the following content.

#!/bin/sh
# Start/stop the git poller
#
### BEGIN INIT INFO
# Provides: git-poller
# Required-Start: stomp
# Short-Description: Gitorious poller
# Description: Gitorious poller
### END INIT INFO
# converted to LaunchDaemon by
# Author: mike jackson (mike.jackson@bluequartz.net)
#

GITORIOUS_ROOT=/Library/WebServer/gitserver.bluequartz.net/gitorious
GIT_POLLER_LOG_FILE=$GITORIOUS_ROOT/log/git-poller_launchdaemon.log

PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
GIT_INSTALL=/usr/local/git
MYSQL_INSTALL=/usr/local/mysql
IMAGEMAGICK_INSTALL=/usr/local/imagemagick
SPHINX_INSTALL=/usr/local/sphinx

PATH=$PATH:$GIT_INSTALL/bin
PATH=$PATH:$GITORIOUS_ROOT/script
PATH=$PATH:$MYSQL_INSTALL/bin
PATH=$PATH:$SPHINX_INSTALL/bin
PATH=$PATH:$IMAGEMAGICK_INSTALL/bin

##
# Process management
##
KillPID ()
{
    local program="$1"
    local pidfile="${PIDFILE:=/$GITORIOUS_ROOT/tmp/pids/${program}0.pid}"
    local     pid=""

    if [ -f "${pidfile}" ]; then
	    pid=$(head -1 "${pidfile}")
	    if ! kill -9 "${pid}" 2> /dev/null; then
	      echo "Bad pid file $pidfile; deleting."
	      pid=""
	      rm -f "${pidfile}"
	    else
	      echo `date` " Killing poller with pid = $pid" >> "$GIT_POLLER_LOG_FILE"
	    fi
    fi

    if [ -n "${pid}" ]; then
	    echo "pdi for poller is ${pid}"
	    rm -f "${pidfile}"
	    return 0
    else
	    return 1
    fi
}

# Check to make sure logs files exist
if [ ! -f $GIT_POLLER_LOG_FILE ]; then
  touch "$GIT_POLLER_LOG_FILE"
fi

case "$1" in
  start)
    echo  `date` " Starting git-poller" >> "$GIT_POLLER_LOG_FILE"
    cd "$GITORIOUS_ROOT" && env RAILS_ENV=production script/poller $@
    ;;
  stop)
    echo `date` " Stopping git-poller" >> "$GIT_POLLER_LOG_FILE"
    KillPID "poller"
    ;;
  *)
    echo $"Usage: $0 {start}"
    RETVAL=1
esac

echo  `date` " git-poller.sh executed with arguments '$@'." >> "$GIT_POLLER_LOG_FILE"

___ DONE

Create stomp init script /etc/init.d/stomp

We need to create a plist file at /Library/LaunchDaemons so that the stompserver process is started up using launchd during boot up.

sudo emacs /Library/LaunchDaemons/com.gitorious.stompserver.plist

and place the following content in this file. If you are running gitorious from a different location on the filesystem then make the appropriate adjustments to the paths:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.gitorious.stompserver</string>
  <key>ProgramArguments</key>
  <array>
  <string>/Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/stompserver.sh</string>
   <string>start</string>
  </array>
  <key>UserName</key>
  <string>git</string>
  <key>RunAtLoad</key>
  <true/>
  <key>OnDemand</key>
  <false/>
</dict>
</plist>

Create the stompserver script in gitorious/launchd/stompserver.sh

mkdir /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/
touch /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/stompserver.sh
chmod u+x /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/stompserver.sh
emacs /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/stompserver.sh

Edit the /Library/WebServer/gitserver.bluequartz.net/gitorious/launchd/stompserver.sh to have the following content:

#!/bin/sh
# Start/stop the stompserver
# WATCH THE LINE WRAPPING BELOW
### BEGIN INIT INFO
# Provides: stomp
# Required-Start: $local_fs $remote_fs $network $syslog
# Short-Description: Stomp
# Description: Stomp
### END INIT INFO

# converted to LaunchDaemon by
# Author: mike jackson (mike.jackson@bluequartz.net)
#

STOMP_ROOT=/Library/Ruby/Gems/1.8/gems/stompserver-0.9.9/
PROG="stompserver"
GITORIOUS_ROOT=/Library/WebServer/gitserver.bluequartz.net/gitorious
STOMPSEVER_LOG_FILE=$GITORIOUS_ROOT/log/stompserver_launchdaemon.log
STOMPSERVER_PID_FILE=$GITORIOUS_ROOT/tmp/pids/stompserver.pid

PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
GIT_INSTALL=/usr/local/git
MYSQL_INSTALL=/usr/local/mysql
IMAGEMAGICK_INSTALL=/usr/local/imagemagick
SPHINX_INSTALL=/usr/local/sphinx

PATH=$PATH:$GIT_INSTALL/bin
PATH=$PATH:$GITORIOUS_ROOT/script
PATH=$PATH:$MYSQL_INSTALL/bin
PATH=$PATH:$SPHINX_INSTALL/bin
PATH=$PATH:$IMAGEMAGICK_INSTALL/bin

# Check to make sure logs files exist
if [ ! -f $STOMPSEVER_LOG_FILE ]; then
  touch "$STOMPSEVER_LOG_FILE"
fi
#------------------------------------------------
log_daemon_msg()
{
  echo `date` " $1"
}
#------------------------------------------------
start_stomp_server()
{
  echo `date` " - Starting $PROG " >> $STOMPSEVER_LOG_FILE
  env RAILS_ENV=production /usr/bin/ruby $STOMP_ROOT/bin/$PROG --working_dir=$GITORIOUS_ROOT
}
#------------------------------------------------
stop_stomp_server()
{
 echo  `date` " - $PROG: Caught Signal and cleaning pid and lock files"  >> $STOMPSEVER_LOG_FILE
  rm -f $STOMPSERVER_PID_FILE
}
#------------------------------------------------
# setup the signal catcher
trap "{ stop_stomp_server; exit 1; }" EXIT

case "$1" in
  start)
    start_stomp_server
    ;;
  *)
    echo $"Usage: $0 {start}"
    RETVAL=1
esac

___ DONE

Install Log Rotation Shell Scripts

OS X has a built-in schedule to run various tasks on a Daily, Weekly or Monthly basis. We are going to integrate with those pre-existing facilities in order to rotate our log files. Create an executable shell script to rotate all the log files on a weekly basis. Note that in the below script the variable 'weeks' controls how many weeks worth of log files are preserved.

sudo touch /etc/periodic/weekly/500.rotate-gitorious
sudo chmod ug+rwx /etc/periodic/weekly/500.rotate-gitorious

Now edit the file to have the following content

#!/bin/sh -

# If there is a global system configuration file, suck it in.
#
if [ -r /etc/defaults/periodic.conf ]
then
    . /etc/defaults/periodic.conf
    source_periodic_confs
fi

GITORIOUS_ROOT=/Library/WebServer/gitserver.bluequartz.net/gitorious
GIT_DAEMON_LOG=git-daemon
GITORIOUS_AUTH_LOG=gitorious_auth
GIT_POLLER_LOG=git-poller
MESSAGE_PROCESSING_LOG=message_processing
PRE_RECEIVE_GUARD_LOG=pre_receive_guard
GITORIOUS_PRODUCTION_LOG=production

cd $GITORIOUS_ROOT/log
# list the log files to rotate
logfiles="$GITORIOUS_PRODUCTION_LOG $GIT_DAEMON_LOG $GITORIOUS_AUTH_LOG $GIT_POLLER_LOG $MESSAGE_PROCESSING_LOG $PRE_RECEIVE_GUARD_LOG "

# Loop through all the log files rotating and compressing the most recent
for file in $logfiles; do
  #echo "Working on $file"
  # Moving all the existing numbered log files
  for (( i = 9; i >= 0; i-- )); do
    #echo "file number $i being evaluated..."
    let "y = i + 1"
    if [ -f "$file.log.$i.gz" ]; then
       #echo  "mv -f '$file.log.$i.gz' '$file.log.$y.gz'"
       mv -f "$file.log.$i.gz" "$file.log.$y.gz"
    fi
  done

  # move current log file into the "0" position
  if [ -f "${file}.log" ]; then
    #echo "Moving file $file.log to $file.log.0.gz"
    mv -f "${file}.log" "${file}.log.0" && if [ -x /usr/bin/gzip ]; then gzip -9 "${file}.log.0"; fi;
  fi

  touch "${f}.log" && chmod 646 "${f}.log" && chown git::_www "${f}.log"
done

# Now restart all the daemons
launchctl unload /Library/LaunchDaemons/com.gitorious.stompserver.plist
launchctl load /Library/LaunchDaemons/com.gitorious.stompserver.plist
launchctl unload /Library/LaunchDaemons/com.gitorious.git-daemon.plist
launchctl load /Library/LaunchDaemons/com.gitorious.git-daemon.plist
# Force a restart of gitorious itself by touching the tmp/restart.txt file
touch $GITORIOUS_ROOT/tmp/restart.txt

exit 0

___ DONE

Generated on Mon Apr 18 11:50:43 2011 for SCMService by  doxygen 1.6.3