Demiazz Harbor

Путанные гиковские мысли о веб-разработке, и вообще.

Shared Git-репозитории

| Комментарии

Нынче настраивая себе сервер на виртуальной машине для собственных нужд, и так для себя, наткнулся на задачку, до приятного и простого решения которой как-то не сразу допер, так как раньше просто не сталкивался с некоторыми возможностями 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 возможности в первую очередь.

За сим откланиваюсь.

Комментарии