22 марта 2012 г. Debian FreeBSD Git Gitolite Linux

FreeBSD и Debian. Установка и настройка Gitolite

В след за статьёй FreeBSD и Debian. Установка и настройка Gitosis хочу рассказать про Gitolite. Это аналогичный по функциональности инструмент, но дающий чуть больше возможностей, например разграничения прав на ветки и теги, и немного проще в использовании. А ещё, в отличие от Gitosis, он до cих пор поддерживается.

Будем считать, что вы уже создали пользователя и группу "git", а также установил Git на сервере.

Gitolite

Иногда для проектов хочется иметь некие "production"-ветки и "release"-теги, но с ограниченным доступом к ним определенным пользователям. Например разработчики имеют доступ только к ветке "master" и собственным веткам созданным на сервере, а "production" должен быть для них недоступен, чтобы по воле случая они туда ничего не намержили плохого.

Git начал становиться очень популярным в корпоративных средах, где обычно есть дополнительные требования в плане контроля доступа. Gitolite изначально был создан, чтобы посодействовать в выполнении таких требований. Но как оказывается он так же полезен и в мире open source: проект Fedora управляет доступом к своим репозиториям пакетов с помощью gitolite. А ведь этих репозиториев больше 10 000! По видимому это самая большая установка gitolite где бы то ни было.

Gitolite позволяет указать права доступа не только для репозиториев, но и для веток или имён меток внутри каждого репозитория. То есть, вы можете указать, что определённые люди (или группы людей) могут отправлять (push) определённые “ссылки” (ветки или метки), а остальные нет.

Pro Git - Pro Git 4.8 Git на сервере Gitolite

Установка Gitolite

FreeBSD:

cd /usr/ports/devel/gitolite
make install clean

Debian:

sudo apt-get install gitolite

Из исходников:

git clone git://github.com/sitaramc/gitolite.git
sudo ./src/gl-system-install

Настройка Gitolite

Для начала нам надо создать на локальной машине ключ и скопировать его на сервер:

ssh-keygen -C "<username>" -t rsa
... укажите путь до файла ключей "/home/<username>/.ssh/git.<hostname>"
scp ~/.ssh/git.<hostname>.pub <username>@<hostname>:<username>.pub

Теперь добавьте в свой локальный «.ssh/config»:

Host git.<hostname>
    User git
    Hostname <hostname>
    Port 22
    IdentityFile ~/.ssh/git.<hostname>

Далее, надо войти на сервер и проинициализировать gitolite:

sudo su - git
gl-setup /home/<username>/<username>.pub
В новых версиях так:
sudo su - git
gitolite setup -pk /home/<username>/<username>.pub

Перейдем снова на локальную машину и попробуем подключится:

ssh git.<hostname> -T
>> hello <username>, this is gitolite v2.3-0-g01e789a running on git 1.7.9.3
>> the gitolite config gives you the following access:
>>      R   W     gitolite-admin
>>     @R_ @W_    testing

Если примерно такой ответ, то есть перечислены репозитории и права, то всё окей, продолжаем!

Пользователи, макросы и права с refex

Теперь склонируем репозиторий "gitolite-admin" к себе и отредактируем конфигурационный файл:

git clone git@git.<hostname>:gitolite-admin gitolite-admin

В полученном репозитории вы увидите каталог "keydir", в котором хранятся все публичные ключи пользователей имеющих доступ к каким-либо репозиториям. Чтобы добавить пользователя, необходимо чтобы вы поместили сгенерированный им публичный ключ в каталог "keydir".

Также, в "gitolite-admin" находится каталог "conf", в котором присутствует конфигурационный файл "gitolite.conf", со следующим содержимым:

repo    gitolite-admin
        RW+     =   <username>, <another-username>

repo    testing
        RW+     =   @all

По содержимому понятно как указывать репозитории, права и пользователей. Также есть специальный макрос "@all", который содержит в себе всех пользователей из "keydir".

Вы можете создавать свои макросы и использовать их в дальнейшем:

@admins    = <username> <username2>
@developers = @admins <username3>  # Some comment
@staff      = @admins @developers

repo    gitolite-admin
        RW+     =   @admins

repo    project
        RW+     =   @developers

Возможности прав:

  • "R" - только чтение refs;
  • "RW" - чтение и запись (в том числе создание новых) refs;
  • "RW+" - чтение, запись (с перезаписью существующих) и удаление refs;
  • "-" - доступ отсутствует;

Refex это регулярные выражения для удаленных (remote) веток, тегов и файлов:

repo  project
    RW+                           = @leaders
    -    production               = @all
    R    refs/heads/experimantal  = @all
    -    refs/heads/experimantal  = @all
    -    refs/tags/rc2000b        = @all
    RW+                           = @all

Если вы не указываете явно префикс "refs/", то gitolite сам дописывает в начале "refs/heads/", поэтому для "- production = @all" будет равносилен "- refs/heads/production = @all".

Права на ветки, теги и файлы

Ну наконец перешли к самому интересному! Для примера сделаем чтобы @leaders имели доступ ко всему, а @developers имели доступ только на чтение к ветке "production" и тегам "rc*" (но не могли создавать такие теги).

repo  project
    RW+ NAME/                 = @leaders
    RW+                       = @leaders

    # Ветка production (с двумя способами ввода)
    R   production            = @developers
    -   refs/heads/production = @developers

    # Теги rc*
    R   refs/tags/rc.*        = @developers
    -   refs/tags/rc.*        = @developers

    # Также вы можете указать конкретные файлы:
    R   NAME/.gitignore       = @developers
    -   NAME/.gitignore       = @developers

    RW+ NAME/                 = @developers
    RW+                       = @developers

Порядок следования правил важен, так как они проверяются последовательно!

Создание репозитория

Чтобы создать новый репозиторий необходимо зайти на сервер и выполнить:

sudo su - git
cd ~/repositories
mkdir someproject.git && cd someproject.git/
git init --bare
>> Initialized empty Git repository in /home/git/repositories/someproject.git/

Теперь откроем файл "gitolite-admin/conf/gitolite.conf" и добавим нужный нам репозиторий:

repo    gitolite-admin
        RW+     =   <username>

repo    someproject
        RW+     =   <username>

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

git commit -am "Added the 'someproject' repo"
git push origin master

Далее, можете получить свой репозиторий:

cd ~
git clone git@gitolite:someproject.git someproject

# или, если у вас уже есть проект
cd ~/someproject
git remote add origin git@gitolite:someproject.git

Это всё. Рекомендую также почитать статью Знакомство с gitolite

Комментарии

если проект в сети, ssh не комфельно, лучше на нативном порте с сжатие

ssh:Could not resolve hostname gitolite: Name or service not known

Не могу подключиться к серверу — ошибка

Kirill, а как вы подключаетесь? Приведите команду.
И покажите свой ~/.ssh/config

Подключаюсь по вашей иструкции, но в общем я разобрался - нужно было добавить

ssh-add
ключ для подключения. Но вот теперь другой вопрос, правда он сильно глупы, но не осуждайте строго, пожалуйста.
1.Как создать, например две ветки(, ) в репозитории(просто указать их в конфиге или как? если можно по подробнее
2.Как поставить ограничение на RW только файлов html и css вот такой группе ?

Но вот теперь другой вопрос, правда он сильно глупы, но не осуждайте строго, пожалуйста.

1.Как создать, например две ветки(ветка1, ветка2) в репозитории(просто указать их в конфиге или как? если можно по подробнее

2.Как поставить ограничение на ветка1 RW только файлов html и css вот такой группе группа1 ?

Kirill,
1. Смотрите комманду git branch (чтобы создать ветки надо выполнить "git branch " и "git branch ")
2. Не знаю, но можно попробовать так:

RW   refs/heads/branch1 NAME/.+\.html NAME/.+\.css  = @developers

или попробовать их разбить на части


RW refs/heads/branch1 = @developers
RW NAME/.+\.html = @developers
RW NAME/.+\.css = @developers

Я может не правильно задал вопрос, но ничего не мешает его переформулировать.

существует ветка, в которую могут писать и читать, только файлы html, группа верстальщики

Я может не правильно задал вопрос, но ничего не мешает его переформулировать.

существует ветка, в которую могут писать и читать только файлы html, и читать все остальные файлы - группа верстальщики

Kirill, я вам уже ответил, сделайте RW для "NAME/.+.html", а R для всего остального "NAME/":


RW NAME/.+\.html = @tech_designer
R NAME/ = @tech_designer

А можно ли ограничивать доступ на файлы/папки? Именно чтобы человек их не видел даже, прочитать не мог.

test, а вы пробовали манипулировать с "NAME/"?

Добрый день!
Спасибо за статью, очень пригодилась.
Ранее работал один, проблем не было. Сейчас нужно выделить доступ только к одной ветке от всего проекта, как ни пытаюсь прочитать можно весь проект всегда.
Я думал вот так должно работать


repo  project
    RW+                       = юзер_с_полным_доступом
    RW test = юзер_с_доступом_только_к_ветке_test

Разобрался, НЕЛЬЗЯ сделать доступной для чтения только одну ветку:

В gitolite есть два уровня контроля доступа. Первый — на уровне репозитория; если у вас есть доступ на чтение (или запись) к любой ссылке в репозитории, то у вас есть доступ на чтение (или запись) к этому репозиторию.

источник

ZiB, вы не правильно истолковали, тут говорится о том, что если у вас есть доступ на репозиторий, то у вас есть доступ на все векти и прочие ссылки.
Но если вы сделаете кому-то доступ только на ветку репозитория, а не весь репозиторий, то все должно получится.

Попробуйте так:


repo  project
    RW+                       = юзер_с_полным_доступом
    RW     test               = юзер_с_доступом_только_к_ветке_test
    -                         = юзер_с_доступом_только_к_ветке_test (либо попробуйте это правило выше вставить, я не помню как именно gitolite проверяет)

ps. Не проверял

Да, нет вроде все правильно.
Приведенный вами код не работает.
Я уже проверил массу комбинаций, но стоит только дать доступ к любой части репозитория, как юзер тут же получает права на чтение всего.

А разве после пуша в gitolite-admin bare-репозиторий сам не создается?

Да, вы правы, но у меня был косяк при таком использовании, после этого я перестал пользоваться этой функциональностью

А если не секрет - что за косяк? Пользую его где-то полгода, проблем с этим пока никаких не заметил.

У меня слетали настройки авторизации, я после очередного добавления репозитория просто не смог получить доступ по ssh, пришлось ручками апдейтится на сервере

Что бы создать новый репозитарий достаточно его прописать в конфиге с правами для пользователей

repo    someproject
        RW+     =   <username>

что бы сделать доступ на определенную ветку

@test_masters_group = user1 user2 user3
@test_developers_group = user4 user5 user6
@test_admins = user7 user8
repo test
   RW  develop$  =  @test_developers_group
   RW  master$   =  @test_masters_group
   RW+                =  @test_admins

Если у вас слетал доступ по ssh нужно внимательно смотреть что пишет hook во время push

Скорее всего у вас ключик был не так оформлен.
По моему опыту gitolite подцепляет ключики ТОЛЬКО если ключик в одну строчку. Файл должен содержать только одну строку, и никаких больше пустых строк, даже после ключа нельзя перевод строки допускать.

в начале строки должно стоять ssh- например ssh-dss или ssh-rsa потом пробел и ключик.
смотрите исходник hook-а как он проверяет ключик.

после добавления ключика и push его на сервер. Если все было сделано правильно, ключик должен появиться в

<git home dir>/.ssh/authorized_keys

Ваша ошибка при распределении прав в том, что нужно после названия ветки ставить знак доллара

Про права доступа: можно еще ставить RWC - добавляет возможность создать ветку RWD - возможность удалять ветку

Еще одна хитрость что бы проверить настройки, если по ssh подсоединиться к серверу под пользователем git с использованием ключа для git вам git-shell выдаст все ваши права, которые вы имеете.

$ ssh git@servername
PTY allocation request failed on channel 0
hello <username>, this is git@<server> running gitolite3 v3.2-0-g5f9789e on git 1.8.1.2

 R W    gitolite-admin
 R W    work
 R W    testing
Connection to svn closed.
$

И еще в настройке прав ВАЖНА последовательность.

например

repo test
    -    master$ = @test_developers_group
    RW+          = @test_developers_group

права будут просматриваться по очереди и для девелопера сначала отработает первое правило, запрещая доступ в мастер, и только потом разрешит доступ в другие места.

если девелопер будет делать push в master то он обломается на первом правиле и hook запретит вносить изменения
если девелопер будет длеать push в другую ветку, то первое правило не сработает, т.к. ветка будет не мастер, а сработает второе правило.

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

Спасибо за комментарий!

Что бы создать новый репозитарий достаточно его прописать в конфиге с правами для пользователей

Я обсуждал это выше

Если у вас слетал доступ по ssh нужно внимательно смотреть что пишет hook во время push

Это да, но иногда информации очень мало

По моему опыту gitolite подцепляет ключики ТОЛЬКО если ключик в одну строчку.

Так вроде так везде

Ваша ошибка при распределении прав в том, что нужно после названия ветки ставить знак доллара

Видимо раньше без знака доллара работало

У меня есть вопрос по настройке прав в самой ОС(я настраиваю gitolite в freebsd 8). Получается,что все репозитарии создаются с правами пользователя git. А у меня цель настроить тестовый веб-сайт, и продакшн веб-сайт, но на одном виртуральном сервере. Т.е. есть тестовый домен site-test.ss, и есть рабочий домен site-work.ss, для обеспечения безопасности они принадлжеат разным пользователям u1 и u2 соотвественно(если иначе никак не сделать, то можно их и под одним пользователем держать).
Для начала ,если можно, объясните, как можно настроить хотя бы тестовый веб-сайт для совместной разработки. Я сделал примерно как написано в статье тут http://www.ibm.com/developerworks/ru/library/wa-git/. И в итоге получил клон сайта с главным репозиторием в gitolite, но т.к. клонировал с репозитория пользователя git , то в итоге папка домена site-test.ss принадлжеит пользователю git.
В общем извиняюсь за столь сложное объяснение, но мне хочется понять ,как можно "разрулить " эти права на файлы. Или получается,что код всех доменов , которые хочется вести под гитом, будет принадлежать одному пользователю git??

Как я понял, вы клонируете через файлы:

git clone /path/to/repository.git <name>

Рекомендую клонировать через ssh:

git clone git.somesite.ss <name>

И не будет таких проблем впринципе

Другая возможность - это указать в одну группу пользователей git, u1, u2.
Делать из под них git clone.

groups u1
pw usermod u1 -G git,<somegroup1>,<somegroup2>
cd /var/lib/git/repositories
chmod -R 770 <reponame>

И потом клонируйте из под нужного пользователя

git clone /var/lib/git/repositories/<reponame>

Благодарю за ответ.
Да, я клонировал под пользователем git через файлы репозитарий project1.git в каталог /home/u1/data/progects/project1 пользователя u1(перед этим под пользователем u1 я сделал bare репозитарий его проекта /home/u1/data/progects/project1, затем склонировал его в папку репозитариев пользователя git /home/git/repositories, примерно руководствуясь разделом "Распределенная Web-разработка с использованием Git" по ссылке,которую приводил выше). В общем я уже сам запутался) и забыл точно ,как делал. И в основном во всех статьях рассказываются действия над одним репозитарием. А мне хочется понять,как связать репозитарий пользователя git, при настроенном gitolite, и папку проекта /home/u1/data/progects/project1 пользователя u1. Если я правильно понял, делается это через хук post-update? И в какой последовательности что нужно клонировать,чтобы этот хук применял изменения, которые происходят в репизитарии пользователя git, на репозитарии /home/u1/data/progects/project1(т.е. тестовом сервере, в папке вирт. хоста Apache сделана символическая ссылка на этот проект)? А при этом программисты по ssh клонируют репозитарий пользователя git, используя возможности gitolite с входом по публичным rsa ключам.

Если вам надо обновлять "клон репозитория пользователя u1" по git-hook post-update, то у вас будет проблема с правами, так как вы будете обновлять из под пользователя "git", то есть все файлы в "клоне репозитория пользователя u1" будут под пользователем git.

Я так не делаю, у меня есть gitolite, он только для хранения репозитория.
Другая задача это деплой (то что у вас, т.е. обновлять репозиторий пользователя u1). В разных проектах я делаю по разному:

Вы конечно можете извратиться и обновлять так:

sudo su - u1 -c "cd ~/project && git pull"

Но вам понадобится наделить правом sudo (/etc/sudoers) пользователя git и при этом с флагом NOPASSWD. Но повторюсь это плохо, изврат и костыль

Либо без sudo, но через ssh. Все тоже самое, но хоть будет меньше проблем с безопасностью

Ясно, вот я и убедился в том, что "gitolite, он только для хранения репозитория") Буду разбираться тогда с Jenkins. Еще раз благодарю за ответы, я просто относительно недавно начал администрировать vds сервер, вот и решил упростить совместную разработку.

Оставьте свой комментарий

Markdown