Тестовые сайты с автоматическим обновлением с svn и авторизацией по учетным данным Redmine

Тестовые сайты с автоматическим обновлением с svn и авторизацией по учетным данным Redmine

Это продолжение статьи о установке Redmine и интеграции svn хранилищ.

Для начала нужно прописать Wildcard DNS record, чтоб при добавлении нового тестового не нужно было постоянно редактировать DNS зону:

*.dev.example.com.   IN  A server_ip

Добавим пользователя, директории и поставим нужные права доступа:

# useradd -d/var/www/cool-project.dev.example.com/www -s/bin/false cool-project
# mkdir -p /var/www/cool-project.dev.example.com/{www,old_document_root,db_backup}
# chmod -R 750 /var/www/cool-project.dev.example.com/
# chgrp cool-project /var/www/cool-project.dev.example.com/
# chown -R cool-project /var/www/cool-project.dev.example.com/www
# touch /var/www/cool-project.dev.example.com/update.sh && chmod 700 /var/www/cool-project.dev.example.com/update.sh

В результате должно получиться так:

# ls -la /var/www/cool-project.dev.example.com/

итого 20
drwxr-x--- 5 root         cool-project 4096 Июн  8 11:25 .
drwxr-xr-x 7 root         root         4096 Июн  8 11:04 ..
drwxr-x--- 2 root         root         4096 Июн  8 11:04 db_backup
drwxr-x--- 2 root         root         4096 Июн  8 11:04 old_document_root
-rwx------ 1 root         root            0 Июн  8 11:25 update.sh
drwxr-x--- 2 cool-project root         4096 Июн  8 11:04 www

Т.е. мы будем запускать каждый сайт от отдельного пользователя, исходники отдельных проектов будут изолированы. Бэкапы исходников и БД будут доступны только руту. Скрипт обновления сможет запускать и править только root (мы будет пускать его через sudo и нельзя позволить пользователю cool-project вносить в него какие-то изменения).

Для запуска скриптов под разными пользователями будем использовать mpm-itk и нам понадобиться mod-auth-mysql для авторизации на тестовых:

# aptitude install apache2-mpm-itk libapache2-mod-auth-mysql
# a2enmod auth_mysql
# /etc/init.d/apache2 restart

Также нужно создать отдельную таблицу для авторизации:

CREATE VIEW users_auth_external AS
SELECT u.login AS username,
       u.hashed_password AS passwd,
       GROUP_CONCAT(p.identifier) AS groups
FROM `members` m
INNER JOIN users u ON m.user_id = u.id
INNER JOIN projects p ON m.project_id = p.id
WHERE u.status = 1
GROUP BY username

Создадим конфиг для виртуального хоста:

# vi /etc/apache2/sites-available/cool-project.dev.example.com
 
<VirtualHost *:80>
    ServerName cool-project.dev.example.com
    ServerAdmin admin@example.com
    DocumentRoot /var/www/cool-project.dev.example.com/www
    Options -Indexes
 
    <Directory /var/www/cool-project.dev.example.com/www>
                AuthType Basic
                AuthName "enter your login/password from redmine" 
                AuthBasicAuthoritative Off
                AuthUserFile /dev/null
                AuthMySQL On
                AuthMySQL_Authoritative      on
                AuthMySQL_Host               localhost
                AuthMySQL_DB                 redmine_default
                AuthMySQL_User               redmine
                AuthMySQL_Password           redmine_password #пароль для доступа к БД Redmine
                AuthMySQL_Password_Table     users_auth_external
                AuthMySQL_Group_Table        users_auth_external
                AuthMySQL_Username_Field     username
                AuthMySQL_Password_Field     passwd
                AuthMySQL_Empty_Passwords off
                AuthMySQL_Group_Field        groups
                AuthMySQL_Encryption_Types   SHA1Sum
                Require group                cool-project
 
        <Limit GET POST>
                require group cool-project
        </Limit>
 
    </Directory>
 
AssignUserID cool-project cool-project
 
</VirtualHost>

Дальше подключим vhost и перечитаем конфиги Apache:

# a2ensite cool-project.dev.example.com
# /etc/init.d/apache2 reload

Создадим скрипт апдейта:

# vi /var/www/cool-project.dev.example.com/update.sh
 
#!/bin/sh
 
path="/var/www/cool-project.dev.example.com"; #path to document root
host="cool-project.dev.example.com";
db_username=cool-project; #username to access db
db_name=cool-project_stag;
db_password="qwerty";
backup_dir="old_document_root";
user="cool-project";
lock_file=`ls $path|grep run.lock`;
wait=yes;
 
echo "Update $host";
 
while [ "$wait" = "yes" ] 
do
        if [ -z "$lock_file" ]; then
                echo "ok, continue"; wait=no;
        else
                echo "another copy running now!"; sleep 60;
        fi;
 
        lock_file=`ls $path|grep run.lock`;
done
touch $path/run.lock;
 
echo "[`date +%H:%M`] update in progress" >> $path/www/public/status.txt;
echo "last update at [`date +%H:%M`]" >> $path/status.txt;
svn info https://dev.example.com/svn-private/cool-project/ | grep "Last" >> $path/status.txt;
svn export --force https://dev.example.com/svn-private/cool-project/trunk/ $path/test_new;
 
mv $path/status.txt $path/test_new/public/;
 
mysqldump -u $db_username -p$db_password $db_name > $path/db_dumps/database_at_`date +%Y-%m-%d-%H-%M-%S`.sql;
chown -R $user $path/test_new/;
 
cp -a $path/www/public/upload/* $path/test_new/public/upload;
 
mv $path/www $path/$backup_dir/test`date +%Y-%m-%d-%H-%M-%S`;
mv $path/test_new $path/www;
chmod -R 777 $path/www/tmp/;
chmod -R 777 $path/www/public/upload/;
 
sed -i s/production/staging/ $path/www/public/.htaccess;
rm $path/www/scripts/common.local.php
sed -i '0,/production/s//staging/' $path/www/scripts/common.php;
env APPLICATION_ENV=staging $path/www/scripts/doctrine migrate > $path/www/migrate_log.txt;
chmod 750 $path/www;
chmod -R 777 $path/www/log/;
rm $path/run.lock;
echo "Update $host complete." 

Я дал пример типичного скрипта апдейта для проекта на Zend. Вам скорее всего нужно будет вносить в него изменения под свои реалии.

Теперь добавим svn hook. При коммите в хранилище будет запускаться скрипт и обновлять наш тестовый сайт:

# cd /var/svn/cool-project/hooks
# cp post-commit.tmpl post-commit && chown www-data post-commit
# vi post-commit

sudo /var/www/cool-project.dev.example.com/update.sh 2>&1 > /dev/null &

Хуки исполняются под www-data и для того, что б менять владельца директории нам придется использовать sudo.

# visudo
www-data ALL=NOPASSWD:/var/www/cool-project.dev.example.com/update.sh

Начиная с версии 1.2.0 Redmine стал добавлять соль в хеши паролей. И если вы хотите использовать авторизацию на тестовых - нужно пропатчить auth_mysql. Патч: mod_auth_mysql.patch

Deb пакеты для Debian squeeze: libapache2-mod-auth-mysql_4.3.9-13_amd64.deb
и Ubuntu 10.04: libapache2-mod-auth-mysql_4.3.9-12ubuntu1_amd64.deb

Ссылки:
Authenticate Apache against Redmine with AuthMySQL
Redmine guide
Руководство по сборке и бэкпортированию deb пакетов