Нынче настраивая себе сервер на виртуальной машине для собственных нужд, и так для себя, наткнулся на задачку, до приятного и простого решения которой как-то не сразу допер, так как раньше просто не сталкивался с некоторыми возможностями Git.
В частности, у меня возникла проблема развертывания Git-хостинга и Redmine-приложения, которые должны работать на одном сервере, и запускаться от разных пользователей для разграничения привилегий.
Описывать то, как поставить Redmine или Gitolite я не собираюсь. Эти задачи во многом более чем тривиальны, и могут быть проделаны даже при небольшом опыте.
Но как всегда не обошлось без подводных камней, об одном из которых хочу предупредить тех, кто еще не сталкивался с таким, но вполне есть вероятность столкнуться.
Что у нас есть?
Имеется сервер с двумя пользователями:
git
- пользователь, от которого работает gitolite;rails-runner
- пользователь, от которого работают Rails-приложения, и в частности нужный нам Redmine.
Суть проблемы
Мы настроили сервер, gitolite отлично работает, Redmine тоже отлично бегает, радует глаз своими возможностями, и все хорошо. Создали проект, добавили хранилище и добавили прямой путь к репозиторию в gitolite для проекта. И думаем, вот сейчас все будет круто.
Но не тут то было. Redmine упорно не находит репозиторий. Вот не видит и все.
Проблема: rails-runner
не имеет доступа к файлам bare-репозитория.
Ложное решение: добавить пользователя rails-runner
в группу git
, и выставить права на все файлы в
репозитории с правами на чтение и выполнение для группы git.
На самом деле, Redmine увидит репозиторий. И тут кроется подводный камень, на который практически сразу натыкаешься после первого же push’а новых коммитов в gitolite-репозиторий.
Redmine снова перестанет видеть репозиторий, так как Git для некоторых каталогов и файлов, которые будут созданы в репозитории не выставит абсолютно никаких прав для всех, кроме владельца. И как раз из-за невозможности прочесть часть файлов, Redmine падает на просмотре репозитория.
Идеальное решение
В голову приходили самые разные решения данной проблемы. Можно было написать hook, можно было сделать mirror и push’ить еще в него к примеру, и еще десяток костылей, которым позавидует даже кобыла, несущая всякую ахинею в Новогоднюю ночь.
А все потому что, в Git уже давно есть очень мощная система конфигурации и в ней есть решение нашей проблемы.
Решение нашей проблемы называется core.sharedRepository
. Эта конфигурация говорит Git’у, какие
права выставлять на вновь создаваемые файлы, и имеет несколько вариантов настройки:
false
- права на доступ к файлам устанавливаются только владельцу;group
,true
- права на доступ к файлам устанавливаются для владельца и группы;all
,world
,everybody
- полные права для любого пользователя;umask
- заданная вручнуюumask
, которая нужна пользователю.
Меняем настройки:
git config --global core.sharedRepository group
и наслаждаемся беспроблемной интеграцией Redmine и gitolite. Redmine не меняет файлы репозитория, так что по сути опасаться нечего, но особые параноики могут выставить свой umask.
После этого выставляем нужные права на уже существующие файлы, чтобы исправить ошибки - и забываем о проблеме, но мотаем на ус, что очень очень и еще раз чертовски очень полезно читать мануалы по настройке ПО, чтобы осознавать его возможности, и не изобретать костыли для решения тривиальных проблем.
Конечно, если у вас Gitolite и Redmine хостятся на разных серверах - то может и понадобится какой-нить плагин к Redmine, или более радикальное решение. Но когда надо расшарить репозиторий в пределах одной машины для нужных пользователей - можно и нужно использовать Git-only возможности в первую очередь.
За сим откланиваюсь.