Sdílené repozitáře verzovacího systému GIT (git, gitweb, gitosis)
Při práci na projektech jako je vývoj aplikací, vytváření dokumentace atd. je dobré mít přehled provedených změn a celkového stavu projektu. To umožňuji systémy pro správu verzí. Slyšet je v současnosti nejvíce o systémech SVN, GIT, CVS, Mercurial a Bazaar. Systémy jsou centralizované (SVN, CVS) nebo distribuované (GIT, Mercurial, Bazaar). V případě centralizovaných systémů všichni uživatelé pracují s jedním sdíleným repozitářem zatímco u distribuovaných si každý uživatel vytváří vlastní lokální kopii sdíleného repozitáře se kterou pracuje.
Při práci na projektech jako je vývoj aplikací, vytváření dokumentace atd. je dobré mít přehled provedených změn a celkového stavu projektu. To umožňuji systémy pro správu verzí. Slyšet je v současnosti nejvíce o systémech SVN, GIT, CVS, Mercurial a Bazaar. Systémy jsou centralizované (SVN, CVS) nebo distribuované (GIT, Mercurial, Bazaar). V případě centralizovaných systémů všichni uživatelé pracují s jedním sdíleným repozitářem zatímco u distribuovaných si každý uživatel vytváří vlastní lokální kopii sdíleného repozitáře se kterou pracuje. Každý má své výhody i nevýhody, výběr vhodného systému zůstává na Vás. V tomto článku se zaměřím na verzovací systém GIT a konfiguraci jeho sdílených repozitářů. GIT je poměrně nový systém, na jeho vývoji začal pracovat Linus Torvalds s jediným účelem – ulehčit správu vývoje linuxového kernelu. Postupně se však rozšířil a v současnosti jej používají pro svůj vývoj například Yahoo, Facebook, Twitter, jQuery, 37 signals a mnoho dalších.
Při práci s GIT repozitáři většinou potřebujeme zajistit jejich zpřístupnění více uživatelům.
V takové situaci nám nezbývá nic jiného, než vytvořit sdílený GIT repozitář, ke kterému budou
mít tito uživatelé přístup. Pro zpřístupnění takového repozitáře musíme nejprve provést
potřebnou konfiguraci na straně serveru. Jak lze taková konfigurace provést si ukážeme zde.
Mějme 3 uživatele: user1, user2 a user3. user1 a user2 mají mít k repozitáři práva čtení i
zápisu zatímco user3 pouze práva ke čtení. Všichni tři uživatelé si přejí mít možnost prohlížet obsah repozitáře
také přímo v internetovém prohlížeči. Server na kterém se bude nacházet sdílený repozitář
nazveme gitserver. Graficky znázorněné zadání vypadá takto:
Začneme vytvořením uživatele s názvem “git”, prostřednictvím něhož uživatelé budou moci přistupovat
k repozitáři. Pokud zatím nemáme na našem lokálním PC vygenerovaný vlastní SSH klíč, vygenerujeme jej:
[localhost:~]$ ssh-keygen -t dsa
Veřejný SSH klíč nahrajeme na server:
[localhost:~]$ scp ~/.ssh/id_dsa.pub root@gitserver:/tmp
A přes SSH se na server přihlásíme:
[localhost:~]$ ssh root@gitserver
Na serveru vytvoříme uživatele “git” s domácím adresářem v cestě /home/git/
:
[gitserver:/]$ useradd -d /home/git git
Do souboru /home/git/.ssh/authorized_keys
vložíme náš SSH klíč:
[gitserver:/]$ cat /tmp/id_dsa.pub > /home/git/.ssh/autorized_keys
Nyní se odhlásíme ze serveru a vyzkoušíme se k němu přihlásit pod uživatelem git:
[localhost:~]$ ssh git@gitserver
Pokud je vše nastaveno správně, přihlášení proběhne bez potřeby zadání přístupového hesla. Nyní musíme na server nainstalovat
potřebné balíčky GITu. Přihlásíme se tedy opět pod superuživatelem a stáhneme balíčky git
a git-core
:
[gitserver:/]$ ssh root@gitserver [gitserver:/]$ yum install git git-core
Repozitáře budeme udržovat v adresáři /home/git/repositories
. V domovském adresáři uživatele git tedy vytvoříme adresář repositories
a v něm adresář projekt.git
, což bude náš první sdílený GIT repozitář:
[gitserver:/]$ mkdir /home/git/repositories [gitserver:/]$ mkdir /home/git/repositories/projekt.git
Stejně jako lokální GIT repozitář musíme i ten sdílený nejdříve inicializovat. Příkazem git init
však vytvoříme i pracovní adresář, který u sdíleného repozitáře nepotřebujeme. Přidáme proto k příkazu parametr --bare
:
[gitserver:/]$ cd /home/git/repositories/projekt.git [gitserver:/home/git/repositories/projekt.git]$ git --bare init Initialized empty Git repository in /home/git/repositories/projekt.git/
Repozitář je nyní připravený a můžeme do něj zapsat z lokálního počítače první commit:
[localhost:~]$ mkdir ~/projekt-l.git [localhost:~]$ cd ~/projekt-l.git [localhost:~/projekt-l.git]$ git init [localhost:~/projekt-l.git]$ touch ZADANI [localhost:~/projekt-l.git]$ git add ZADANI [localhost:~/projekt-l.git]$ git commit -m "Pridano zadani" [localhost:~/projekt-l.git]$ git remote add gitserver git@gitserver:repositories/projekt.git [localhost:~/projekt-l.git]$ git push gitserver master
Stejně tak jej můžeme klonovat:
[localhost:~]$ mkdir ~/projekt-clone.git [localhost:~]$ cd ~/projekt-clone.git [localhost:~/projekt-clone.git]$ git clone git@gitserver:repositories/projekt.git
Všichni uživatelé, kteří mají svůj SSH klíč na serveru v souboru /home/git/authorized_keys
mohou s repozitářem pracovat, mají k němu plná práva. Přístup k serveru mají také přes SSH, což není vždy žádoucí. Změnou shellu uživatele git na shell /usr/bin/git-shell
v /etc/passwd
jim tento přístup můžeme odebrat. Při pokusu o přístup k serveru pod uživatelem git bude uživatelům vracena tato hláška:
[localhost:~]$ ssh git@gitserver fatal: What do you think I am? A shell? Connection to gitserver closed
My tuto změnu kvůli následnému použití nástroje Gitosis provádět nebudeme. Tím máme první část zadání hotovou. Nyní uživatelům umožníme zobrazovat obsah repozitáře v internetovém prohlížeči.
Gitweb – webové rozhraní GITu
Gitweb je CGI skript představující webové rozhraní pro GIT repozitáře. V tomto článku předpokládám na serveru připravený webový server Apache, který bude Gitweb obsluhovat. Nejdříve vytvoříme nového VirtualHost-a:
[gitserver:/]$ cd /etc/httpd/vhosts.d/ [gitserver:/etc/httpd/vhosts.d]$ touch gitweb.conf
Obsah gitweb.conf
bude vypadat takto:
<VirtualHost *:80> ServerName gitserver DocumentRoot /srv/vhosts/gitweb <Directory /var/www/git> Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch AllowOverride All order allow,deny Allow from all AddHandler cgi-script cgi DirectoryIndex gitweb.cgi </Directory> </VirtualHost>
Z obsahu je jasně, že Apache bude očekávat Gitweb v adresáři /srv/vhosts/gitweb
. Nejdříve nainstalujeme Gitweb z balíčku:
[gitserver:/]$ yum install gitweb
Po instalaci se nachází v adresáři /var/www/git
, přesuneme ho proto do adresáře /srv/vhosts/gitweb
.
[gitserver:/]$ mkdir /srv/vhosts/gitweb [gitserver:/]$ cp -r /var/www/git/* /srv/vhosts/gitweb/
Otevřeme skript /srv/vhosts/gitweb/gitweb.cgi
a upravíme v něm cestu k našim repozitářům:
our $projectroot = "/home/git/repositories";
Aby mohl Apache přistupovat do domácího adresáře uživatele git, přidáme jej do jeho skupiny. Skupině přiřadíme práva čtení a spouštění:
[gitserver:/]$ usermod -G git apache [gitserver:/]$ chmod g+rx /home/git
Spustíme webový server Apache:
[gitserver:/]$ /etc/init.d/httpd start
Na lokálním počítači si v souboru /etc/hosts
nastavíme překládání adresy gitserver
na ip adresu gitserveru (v mém případě je to 192.168.1.4):
192.168.1.4 gitserver
Nyní v internetovém prohlížeči můžeme přejít na adresu http://gitserver kde se nám zobrazí rozhraní Gitwebu:
Protože uživatele nechceme mučit základním vzhledem, nainstalujeme jim vzhled od Stefana Imhoffa (https://github.com/kogakure/gitweb-theme) inspirovaný službou github.com:
[gitserver:/tmp]$ git clone https://github.com/kogakure/gitweb-theme.git [gitserver:/tmp]$ cp gitweb-theme/gitweb.css /srv/vhosts/gitweb/
Výsledné rozhraní Gitwebu pro uživatele vypadá takto:
Tímto jsme uživatelům zpřístupnili webové rozhraní pro zobrazení repozitářů. Abychom splnili zadání, musíme ještě uživatelům přiřadit práva pro přístup k repozitářům. K tomu použijeme nástroj Gitosis.
Gitosis – nástroj pro správu GIT repozitářů
Nejdříve si naklonujeme repozitář s Gitosis a nainstalujeme ho:
[gitserver:/tmp]$ git clone git://eagain.net/gitosis.git [gitserver:/tmp]$ cd gitosis [gitserver:/tmp/gitosis]$ python setupy.py install
Nyní je ho potřeba inicializovat. Gitosis se vždy inicializuje do domácího adresáře uživatele pod kterým je skript gitosis-init spuštěn, proto jej musíme spustit pod uživatelem git. Zároveň se Gitosis při inicializaci sám postará o vložení veřejného SSH klíče do souboru authorized_keys
, odstraníme tedy z authorized_keys
klíč který jsme do něj dříve přidali:
[gitserver:/home/git]$ echo "" > .ssh/authorized_keys [gitserver:/home/git]$ gitosis-init < /tmp/id_dsa.pub [gitserver:/home/git]$ sudo -H -u git gitosis-init < /tmp/id_dsa.pub Initialized empty Git repository in ./ Reinitialized existing Git repository in ./
V adresáři /home/git/repositories
se vytvořil repozitář s názvem gitosis-admin.git
. Naklonujeme si ho na lokální počítač:
[localhost:~]$ git clone git@gitserver:gitosis-admin.git
Obsahem repozitáře je soubor gitosis.conf
a adresář keydir
. V adresáři keydir
se uchovávají SSH klíče všech uživatelů, gitosis.conf
zatím obsahuje defaultní konfiguraci. Do adresáře keydir
nakopírujeme veřejné klíče uživatelů user1, user2 a user3:
[localhost:~/gitosis-admin]$ cp /tmp/user1.pub /tmp/user2.pub /tmp/user3.pub keydir/
A v souboru gitosis.conf
upravíme konfiguraci dle zadání:
[gitosis] [group gitosis-admin] writable = gitosis-admin members = filip [group programatori] writable = projekt members = user1 user2 [group programatori_readonly] readonly = projekt members = user3
V konfiguraci jsme vytvořili skupinu programatori, která může zapisovat do repozitáře projekt.git
. Do skupiny jsme přiřadili uživatele user1 a user2 (název uživatele odpovídá názvu souboru s SSH klíčem v adresáři keydir
bez koncovky .pub). Další skupina se nazývá programatori_readonly. Tato skupina má pouze práva ke čtení repozitáře projekt.git. Do skupiny jsme přiřadili uživatele user3. Zbývá změny nahrát zpět na server:
[localhost:~/gitosis-admin]$ git add * [localhost:~/gitosis-admin]$ git commit -m "Pridana skupina programatoru" [localhost:~/gitosis-admin]$ git push
Je na čase konfiguraci otestovat:
[user1@localhost:~]$ git clone git@gitserver:projekt.git Initialized empty Git repository in /home/user1/projekt/.git/ remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0) Receiving objects: 100% (3/3), done. [user1@localhost:~]$ cd projekt [user1@localhost:~/projekt]$ touch POZNAMKY [user1@localhost:~/projekt]$ git add POZNAMKY [user1@localhost:~/projekt]$ git commit -m "pridany poznamky" [user1@localhost:~/projekt]$ git push Counting objects: 3, done. Delta compression using up to 2 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (2/2), 244 bytes, done. Total 2 (delta 0), reused 0 (delta 0) To git@gitserver:projekt.git 6f421f2..51f184f master -> master
[user3@localhost:~]$ git clone git@gitserver:projekt.git Initialized empty Git repository in /home/user3/projekt/.git/ remote: Counting objects: 5, done. remote: Compressing objects: 100% (3/3), done. remote: Total 5 (delta 0), reused 0 (delta 0) Receiving objects: 100% (5/5), done. [user3@localhost:~]$ cd projekt [user3@localhost:~/projekt]$ echo "@user3" > POZNAMKY [user3@localhost:~/projekt]$ git commit -a -m "Pridana poznamka od uzivatele user3" [user3@localhost:~/projekt]$ git push ERROR:gitosis.serve.main:Repository write access denied fatal: The remote end hung up unexpectedly
User1 může v pořádku číst i zapisovat do repozitáře zatímco user3 jej může pouze číst. Konfigurace tedy odpovídá zadání.
Další možnosti konfigurace Gitosis
Jak jste si možná všimli, Gitweb zobrazuje kromě repozitáře projekt.git
i repozitář gitosis-admin.git
. Pokud byste ho radši ve výpisu neměli, stačí upravit konfiguraci. Obsah gitosis.conf
upravte takto:
[gitosis] gitweb = no [group gitosis-admin] writable = gitosis-admin members = filip [group programatori] writable = projekt members = user1 user2 [group programatori_readonly] readonly = projekt members = user3 [repo projekt] gitweb = yes
S touto konfigurací Gitweb bude zobrazovat pouze ty repozitáře, které mají v gitosis.conf explicitně uvedeno jejich zobrazení. Ve skutečnosti to však znamená, že tyto repozitáře bude Gitosis uvádět v souboru /home/git/gitosis/projects.list
. Tento seznam tedy musíme předat Gitwebu. Předáme ho změnou řádku v gitweb.conf
:
# source of projects list our $projects_list = "/home/git/gitosis/projects.list";
Po této změně Gitweb zobrazí pouze repozitář projekt.git
. Dále je možné v konfiguraci repozitáře nastavit vlastníka a popis repozitáře (zobrazuje Gitweb). To provedete takto:
[repo projekt] gitweb = yes owner = Filip Bartoš description = Testovací projekt
Další možná nastavení najdete v repozitáři Gitosis-u v souboru example.conf
.
Kam dál?
Pro další informace o GITu doporučuji navštivit tyto zdroje:
http://progit.org/
http://whygitisbetterthanx.gitfu.cz/
http://gitcasts.com/
Autorem všech těchto webů je Scott Chacon. ProGit byl přeložen do češtiny společností CZ.NIC. V .pdf si ji můžete stáhnout zde: http://knihy.nic.cz/.