Git repository via Apache – Take 3

I revisited an old post that I wrote to see how to host my own private git repository with Apache, but I didn’t write any details and made it hard on myself, so I’ll try to fix that here.

My setup

  • Anonymous read access, user/password protected write access
  • Ubuntu 14.04
  • Apache 2.4
  • Git 1.9.1

Step 1. Enable the prerequisite modules.

I had to add symlinks in /etc/apache2/mods-enabled for the rewrite and cgi modules. These are already available with a vanilla install, so look for rewrite.load and cgi.load in the mods-available folder.

In addition, you need to explicitly enable the rewrite module in the virtual host setup in the vanilla apache2 install. I added these lines right under the log defines in sites-enabled/000-default.conf:

RewriteEngine On
RewriteOptions Inherit

Step 2. Set up the git repositories.

I set up all my repositories under /path/to/git, e.g. /path/to/git/project1.git/, etc. The repositories have to be set up in a specific way to enable push. Here’s a script I use:

#!/bin/bash
if [[ $# < 1 ]]; then
    echo Usage: `basename $0` repo-name
    exit 0
fi
cd /path/to/git
if [[ -e ${1}.git ]]; then
    echo ${1}.git exists
    exit 0
fi
mkdir ${1}.git
cd ${1}.git
git init --bare
git config http.receivepack true
git update-server-info
touch git-daemon-export-ok
cd ..
sudo chown -R www-data:www-data ${1}.git

Step 3. Set up a users list with htpasswd.

  1. Install apache2-utils
  2. htpasswd -c /path/to/git/users.txt username

Step 4. Set up a git config.

Put this in, say, git.conf under /etc/apache2/confs-available, and

SetEnv GIT_PROJECT_ROOT /var/www/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

RewriteCond %{QUERY_STRING} service=git-upload-pack [OR]
RewriteCond %{REQUEST_URI} /git-upload-pack$
RewriteRule ^/git/ - [E=AUTHNOTREQUIRED:yes]

<LocationMatch "^/git/">
    Require env AUTHNOTREQUIRED
    AuthType Basic
    AuthName "Git access"
    AuthUserFile /path/to/git/users.txt
    Require valid-user
</LocationMatch>

Remarks

I spent way too much time on this because of a mismatch between git and apache documentation. Basically, the authorization directives were specific to Apache 2.2 but I was working with Apache 2.4 – see here under runtime configuration changes where they mention that they have a new authorization module mod_authz_host. Also, because I’m not a sysadmin, I didn’t realize that I had to add “RewriteEngine On” so I was scratching my head about why the environment variable was never getting set.

Anyways, I hope the above saves someone some time. I promise not to write any tutorial blogs that only link to documentation without adding anything because, as you can see, reading manuals does not solve problems.

Building OpenJDK under Ubuntu

Shame: There was a typo in the command to clone jdk7 from the repo. The command below is now correct. Apologies for the confusion 😦

Manually building a large project really gives me an appreciation for how well the portage system in Gentoo automates the build process. To think that the process of pulling in dependencies, getting the source, applying patches, configuring, building, and merging binaries into a live system is executed by contributed ebuild scripts is very amazing, especially when you see it all before your very eyes. Unfortunately, searching for dependencies and setting up your build environment can be hectic, and the less patient miss out on an awesome experience.

This guide is dedicated to building OpenJDK entirely from the command line under Ubuntu 8.04. Assume all commands are executed in the directory where we will do all our work. Also, don’t forget to replace the instances of atsui (my username) with your own 😛

Install and configure Mercurial

First we’ll set up Mercurial, a distributed source control tool.

sudo apt-get install mercurial

We also want to set up Forest, an Mercurial extension that will let us recursively pull the entire OpenJDK from the repository. This command uses Mercurial to grab the extension and put it under the forest folder, which contains a python script we want called forest.py.

hg clone http://bitbucket.org/pmezard/hgforest-crew forest

Paste the following into .hgrc under your home directory to set up Forest.

[ui]
username = atsui
[extensions]
forest=/path/to/forest.py
fetch=

You can check it works by typing in a command provided by Forest, eg.

hg fclone

Clone a copy of OpenJDK

Now let’s grab the JDK! This command puts everything in jdk7:

hg fclone http://hg.openjdk.java.net/jdk7/jdk7 jdk7

Fetch the binary plugs

OpenJDK still depends on some closed source blobs, which can be acquired and unpacked as follows:

wget http://www.java.net/download/openjdk/jdk7/promoted/b48/jdk-7-ea-plug-b48-linux-i586-19_feb_2009.jar

# accept the license agreement and install to cwd
java -jar jdk-7-ea-plug-b48-linux-i586-19_feb_2009.jar

Judging from the filename, perhaps this is frequently updated. Check out the downloads for the latest file.

Install library dependencies

Building from source often happens against various other libraries. Here is some of what I found was needed:

sudo apt-get install build-essential gawk libasound2-dev libfreetype6-dev libcups2-dev libxt-dev libx11-dev libxtst-dev

Configure the build environment

These commands will configure the build environment, but you should manually check your environment variables and unset anything related to java! A mysterious problem I ran into on my Gentoo box had to do with the fact that although I had unset JAVA_HOME and CLASSPATH, which the makefile checks for, I still had JAVAC and JDK_HOME set, which caused some mysterious hidden package errors. Find them and unset them before you build. The last command will check to see if the environment is reasonably prepared.

export ALT_BOOTDIR=/usr/lib/jvm/java-6-sun
export ALT_BINARY_PLUGS_PATH=/path/to/openjdk-binary-plugs
export LANG="C"
unset JAVA_HOME
unset CLASSPATH
cd jdk7
make sanity

Build OpenJDK

This will start the build, which may halt on missing dependency errors.

make

Watch 24

Go and enjoy an episode of 24. Actually, the build takes a little longer than the time of one episode, so maybe you can make some popcorn while you’re at it.

With any luck, you will see this when you come back:

Control linux i586 1.7.0-internal build_product_image build finished:
Control linux i586 1.7.0-internal all_product_build build finished:
Control linux i586 1.7.0-internal all build finished:

You can then run

build/linux-i586/bin/java -version

to test your freshly baked OpenJDK, which should give something like

openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-atsui_2009_02_20_21_40-b00)
OpenJDK Client VM (build 15.0-b01, mixed mode)

Hopefully, that was pretty painless. Enjoy 🙂