2013/06/03

RHEL 5 安裝 Indefero

http://www.indefero.net

Indefero 是一個 Web 介面 Git 的前端工具,類似 Gitorious。
簡單說,它就是類似 Google Code 那樣的原始碼管理系統。
其實它可以接管 Git、Subversion、Mercurial、Monotone 等 SCM 軟體。
Indefero 是使用 PHP 撰寫的,搭配 Pluf 框架。



【Setup Indefero with Git in RHEL 5.x】

[修改 /etc/hosts]

127.0.0.1    indefero

[MySQL 資料庫]
資料庫版本:MySQL 5.x
資料庫帳號:indefero
資料庫密碼:indefero
資料庫名稱:indefero

mysql -u root -p
mysql> create database indefero;
mysql> ALTER DATABASE indefero CHARACTER SET utf8 COLLATE utf8_general_ci;
mysql> grant all privileges on indefero.* to indefero@localhost identified by 'indefero';

[相關使用者]

手動新增的使用者:git
httpd 預設的使用者:apache

[相關路徑]
/home/git/repositories
/home/git/.ssh
/var/www/html/indefero
/var/www/html/pluf

[1]安裝 Pluf 框架

Pluf:http://www.pluf.org

Pluf 需要至少 5.2.4 版本以上的 PHP,RHEL 5.x 附帶的通常都很舊。
RHEL 5.x 需要的 rpm 套件可以去這找:http://rpms.famillecollet.com

先使用 yum 安裝必須的 PHP 套件:

yum install php-pear
yum install php-pear-Mail php-pear-Mail-Mime php-pear-mail_mime

下載 Pluf 原始檔到 /var/www/html 并解壓縮,完成。

[2]安裝 Indefero

前往:http://projects.ceondo.com/p/indefero/

下載 Indefero 原始檔到 /var/www/html,解壓縮,然後執行:

cd /var/www/html/indefero
cp src/IDF/conf/idf.php-dist src/IDF/conf/idf.php
cp src/IDF/conf/path.php-dist src/IDF/conf/path.php

確認 MySQL 資料庫與資料庫使用者。

修改 src/IDF/conf/idf.php:

$cfg['git_repositories'] = '/home/git/repositories/%s.git';
$cfg['git_remote_url'] = 'git://indefero/%s.git';
$cfg['git_write_remote_url'] = 'git@indefero:%s.git';
$cfg['send_emails'] = false;
$cfg['mail_backend'] = 'smtp';
$cfg['mail_host'] = 'localhost';
$cfg['mail_port'] = 25;
$cfg['url_base'] = 'http://indefero';
$cfg['url_media'] = 'http://indefero/media';
$cfg['url_upload'] = 'http://indefero/media/upload';
$cfg['upload_path'] = '/var/www/html/indefero/www/media/upload';
$cfg['upload_issue_path'] = '/var/www/html/indefero/attachments';
# 超過 40 個字元就可以
$cfg['secret_key'] = 'abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd';
# Database configuration
$cfg['db_login'] = 'indefero';
$cfg['db_password'] = 'indefero';
$cfg['db_database'] = 'indefero';
$cfg['db_server'] = 'localhost';
$cfg['db_version'] = '5.1';
$cfg['db_table_prefix'] = 'indefero_';
$cfg['db_engine'] = 'MySQL';
# 如果有碰到 open_basedir restriction error,
# 執行 cp /etc/mime.types /home,并開啟以下設定:
#$cfg['idf_mimetypes_db'] = '/home/mime.types';

修改 src/IDF/conf/path.php:

# 如果沒有特殊修改,使用預設的相對路徑即可。

開始安裝:

cd /var/www/html/indefero/src
# 以下命令進行測試安裝
php /var/www/html/pluf/src/migrate.php --conf=IDF/conf/idf.php -a -i -d -u
# 以下命令進行實際安裝
php /var/www/html/pluf/src/migrate.php --conf=IDF/conf/idf.php -a -i -d

建立 /var/www/html/indefero/www/bootstrap.php:

require '/var/www/html/indefero/src/IDF/conf/path.php';
require 'Pluf.php';
Pluf::start('/var/www/html/indefero/src/IDF/conf/idf.php');
Pluf_Dispatcher::loadControllers(Pluf::f('idf_views'));

$user = new Pluf_User();
$user->first_name = '管理者姓氏';
$user->last_name = '管理者名字'; // Required! 必須!
$user->login = '管理者帳號'; // must be lowercase! 全部小寫!
$user->email = '管理者信箱';
$user->password = '管理者密碼';
$user->administrator = true;
$user->active = true;
$user->create();
print "Bootstrap ok\n";


建立管理者:

php /var/www/html/indefero/www/bootstrap.php

順利執行完成後,可以刪除或改名 bootstrap.php 檔。

建立 /etc/httpd/conf.d/indefero:

# 請自行把 [ ] 換成 < >
[virtualhost *:80]
    ServerName indefero
    DocumentRoot /var/www/html/indefero/www
    ErrorLog logs/indefero-error_log
    CustomLog logs/indefero-access_log common
[/VirtualHost]
[directory /var/www/html/indefero/www]  
    AllowOverride All
[/Directory]

在 /var/www/html/indefero/www 內補一個 .htaccess:

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) /index.php/$1

重新啟動 Apache:

service httpd restart

連到 http://indefero 登入看看。

[3]設定 Git Repositories

Indefero 原始檔的 doc 資料夾下,有完整的設定說明檔(doc/syncgit.mdtext)。

建立使用者用以控制 Indefero 的 Git Repositories:

useradd git
mkdir /home/git/repositories
mkdir -p /home/git/.ssh
touch /home/git/.ssh/authorized_keys
chown -R git.git /home/git
chmod 0700 /home/git/.ssh
chmod 0600 /home/git/.ssh/authorized_keys

把 httpd 的控制者加到 Git Repositories 控制者的群組:

usermod -a -G git apache

確認系統可以執行 python 程式,因為後面需要執行 scripts/gitserver.py。

python -v

重新修改 src/IDF/conf/idf.php 內的設定:

$cfg['git_repositories'] = '/home/git/repositories/%s.git';
$cfg['git_remote_url'] = 'git://indefero/%s.git';
$cfg['idf_plugin_syncgit_path_gitserve'] = '/var/www/html/indefero/scripts/gitserve.py';
$cfg['idf_plugin_syncgit_path_authorized_keys'] = '/home/git/.ssh/authorized_keys';
$cfg['idf_plugin_syncgit_sync_file'] = '/tmp/SYNC-GIT';

# Remove the git repositories which do not have a corresponding project
# This is run at cron time
$cfg['idf_plugin_syncgit_remove_orphans'] = false;

# git account home dir
$cfg['idf_plugin_syncgit_git_home_dir'] = '/home/git'; 

# where are going to be the git repositories
$cfg['idf_plugin_syncgit_base_repositories'] = '/home/git/repositories'; 

使用 git 的身份加入一下 Cron job:

* * * * * php /var/www/html/indefero/scripts/gitcron.php


安裝 git-daemon:
yum install git-daemon

制作一個 Git Daemon 寫在 /etc/event.d/local-git-daemon:
start on startup
stop on shutdown
exec /usr/bin/git-daemon \
--user=git --group=git \
--verbose \
--reuseaddr \
--base-path=/home/git/repositories/ \
/home/git/repositories/
respawn

啟動:
start local-git-daemon


使用網友寫的 git-daemon,編寫到 /etc/init.d/git-daemon:
(http://projects.ceondo.com/p/indefero/page/git-daemon-sysV-InitScript/)

#!/bin/sh
### BEGIN INIT INFO
# Provides: git-daemon
# Required-Start: $network $remote_fs $syslog
# Required-Stop: $network $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: git-daemon service
# Description: git-daemon makes git repositories available via the git
# protocol.
### END INIT INFO

# Author: Benjamin Graham "bman@duuit.com"

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/lib/git-core
DESC="git-daemon service"
NAME=git-daemon
DAEMON=/usr/bin/$NAME
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Fallback options values, we use these when
# the /etc/default/git-daemon file does not exist
RUN=no
USER=git
GROUP=git
REPOSITORIES="/home/git/repositories/"

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# If ADVANCED_OPTS is empty, use a default setting
if [ "x$ADVANCED_OPTS" == "x" ];
then
    ADVANCED_OPTS="--base-path=$REPOSITORIES $REPOSITORIES"
fi

DAEMON_ARGS="--syslog --reuseaddr \
$ADVANCED_OPTS"

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null || return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --background --make-pidfile -- $DAEMON_ARGS || return 2

return 0
}

#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
}

case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;

esac
/etc/default/git-daemon

# Defaults for the git-daemon initscript

# Set to yes to start git-daemon
RUN=yes

# Set to the user and group git-daemon should run as
USER=git
GROUP=git

# Set the base path and the directory where the repositories are.
REPOSITORIES="/home/git/repositories/"

# Provide a way to have custom setup.
#
# Note, when ADVANCED_OPTS is defined the REPOSITORIES setting is ignored,
# so take good care to specify exactly what git-daemon have to do.
#
# Here is an example from the man page:
#ADVANCED_OPTS="--verbose --export-all \
# --interpolated-path=/pub/%IP/%D \
# /pub/192.168.1.200/software \
# /pub/10.10.220.23/software"
ADVANCED_OPTS="/usr/lib/git-core/git-daemon \ 
--verbose --base-path=/home/git/repositories \
 /home/git/repositories"

啟動:

chmo a+x /etc/init.d/git-daemon
/etc/init.d/git-daemon start
service httpd restart



【關于 /home/git/repositories】

Git 其實可以 init 一個 bare repository(裸倉儲庫),bare repository 預設允許任何人 push。
實際的 Git 命令是:
cd some_directory && git init --bare

Indefero(大部分相似的系統)正是利用這個 Git 命令幫助使用者建立專案的 Repository。
Indefero 會根據使用者 create project 時給的 project name,
到 /home/git/repositories 內,建立 project_name.git 這種類型的資料夾,
再切換到該資料夾內,使用 git init --bare 初始化這個 Repository。



【版本升級】

備份舊的 Pluf 與 Indefero 資料夾:

cp -r pluf pluf_backup
cp -r indefero indefero_backup

備份舊的 Indefero 資料庫:

mysqldump -u indefero -p --databases indefero > indefero_backup.sql

下載最新的 Pluf 與 Indefero 原始檔,並解壓縮取代掉原本的資料夾。
然後執行資料庫升級:

cd /home/git/public_html/indefero/src
# 測試升級動作
$ php /home/git/public_html/pluf/src/migrate.php --conf=IDF/conf/idf.php -a -d -u
# 執行升級動作
$ php /home/git/public_html/pluf/src/migrate.php --conf=IDF/conf/idf.php -a -d 

重啟 Apache 檢查:
service httpd restart 



【錯誤修正】

[idf_plugin_syncgit_base_repositories]
http://projects.ceondo.com/p/indefero/issues/198/

[Getting Write Access to Git Repositories]
http://www.openflow.org/wk/index.php/Git

Reference:
01. http://projects.ceondo.com/p/indefero/page/Installation/
02. http://code.google.com/hosting/
03. https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools
04. http://www.pluf.org/doc/install.html
05. http://zx-1986.blogspot.com/2010/08/git-manual.html