Administrowanie Systemami Komputerowymi Konfiguracja serwera Apache jako serwera repozytorium kodu SVN Laboratorium nr 4 Instrukcja Tomasz Boiński
Wstęp Systemy kontroli wersji to najczęściej wykorzystywane narzędzia pracy grupowej stosowane przez programistów. Narzędzia te znacznie usprawniają procedurę współdzielenia kodu przez zespół programistów, umożliwiają sprawną integrację zmian wprowadzonych w jednym pliku przez wiele osób, a także śledzenia aktywności poszczególnych programistów czy też wskazanie osoby odpowiedzialnej za poszczególne zmiany. Subversion jest obecnie, obok git, najpopularniejszym systemem kontroli wersji, pomimo swojej relatywnej prostoty. Narzędzie to umożliwia współdzielenie kodu tylko w postaci scentralizowanej (Rys. 1). Rys. 1: Model pracy zastosowany w Subversion Model ten, pomimo małej elastyczności jest wystarczający dla większości zastosowań zarówno dla małych jak i średnich projektów. Ponadto Subversion jest rozwiązaniem bardzo uniwersalnym dzięki zastosowaniu protokołu HTTP a mnogość narzędzi pomocniczych znacznie upraszcza korzystanie z niego. Instalacja i konfiguracja Subversion Aby móc skorzystać z Subversion w pierwszej kolejności należy go zainstalować. Narzędzie to dostępne jest zarówno dla Windows jak i Linux i można je pobrać ze strony http://subversion.tigris.org/. W przypadku systemów linuksowych jest on też zazwyczaj dostępny w repozytoriach dystrybucji, więc można go zainstalować poprzez standardową aplikację do zarządzania pakietami jak yum (Fedora), yast (opensuse) czy apt-get (Debian). Do pełnego działania konieczne jest też zainstalowanie serwera www, np. Apache i wtyczki do niego umożliwiającej współpracę z Subversion. W przypadku apache jest to mod_svn i mod_autz_svn. W systemie Debian odpowiednie pakiety to: apache2, subversion, libapache2-svn. Pozostałe wymagane zostaną zainstalowane jako zależności. 1. Proces tworzenia repozytorium jest bardzo prosty. W tym celu należy: 1. utworzyć katalog służący jako zbiorczy dla różnych repozytoriów będzie potrzebne do dalszej części zajęć, w dalszej instrukcji będę się do tego katalogu odnosił jako $repos. W każde takie miejsce należy w trakcie wykonywania zadań wstawić rzeczywistą ścieżkę do tego katalogu 2. w katalogu $repos utworzyć katalog dla właściwego repozytorium, w dalszej części instrukcji będę się do tego katalogu odnosił jako do $repozytorium. W każde takie miejsce należy wstawić nazwę tego katalogu bez ścieżki
3. uruchomić terminal i wykonać polecenie svnadmin create $repos/ $repozytorium po tym kroku w katalogu z repozytorium zostaną utworzone dane kontrolne a repozytorium jest gotowe do przechowywania danych 2. Konfiguracja serwera Apache jako serwera svn 1. Utworzenie pliku z użytkownikami w tym celu należy użyć polecenia htpasswd: 1. tworzenie pierwszego użytkownika: htpasswd -c <ścieżka do pliku> <nazwa użytkownika> 2. i każdego kolejnego htpasswd <ścieżka do pliku> <nazwa użytkownika> Po każdym wywołaniu tego polecenie poproszeni zostaniemy o dwukrotne podanie hasła dodawanego użytkownika. Jeżeli użytkownik w pliku już istnieje to jego hasło zostanie zmienione na nowo podane. Proszę utworzyć przynajmniej 3 użytkowników. Należy koniecznie zwrócić uwagę, by przy kolejnych wywołaniach polecenia htpasswd nie używać opcji -c. Powoduje ona utworzenie i nadpisanie istniejącego pliku! W dalszej części instrukcji do pliku z hasłami odnosić się będę w postaci $htpasswd. 2. W systemie apache do zarządzania modułami służą polecenia: 1. a2enmod aktywacja modułu 2. a2dismod dezaktywacja modułu Oba polecenia przyjmują jeden parametr i jest to nazwa modułu. Aby znaleźć nazwę właściwego moduły należy zajrzeć do katalogu /etc/apache2/mods-available. Nazwa modułu to nazwa jego pliku konfiguracyjnego bez rozszerzenia. Moduły aktywowane znajdują się w katalogu /etc/apache2/mods-enabled. 3. Aktywujemy moduł svn (w naszym przypadku jest to moduł o nazwie dav_svn) 4. Należy wyedytować plik /etc/apache2/mods-enabled/dav_svn.conf. Tam znajdować się będzie cała konfiguracja repozytoriów i svn. 5. Jeżeli z jakiegoś powodu serwer apache będzie narzekał, że nie może znaleźć odpowiednich modułów czy nie rozpoznaje dyrektyw, konieczne może być załadowanie dodatkowych modułów, czyli: LoadModule dav_module LoadModule dav_svn_module LoadModule authz_svn_module <ścieżka>/mod_dav.so <ścieżka>/mod_dav_svn.so <ścieżka>/mod_authz_svn.so Pierwszy z modułów odpowiada za obsługę katalogów WebDAV, czyli zapisu i odczytu plików za pośrednictwem serwera WWW, drugi moduł odpowiada za obsługę samego repozytorium i rozumienie przez serwer WWW znaczenia poszczególnych zawartych w nim plików i katalogów systemowych, trzeci jest odpowiedzialny za uwierzytelnianie dodatkowe, które będziemy używać w dalszej części laboratorium. W Debianie należy je dodać do pliku /etc/apache2/mods-enabled/dav_svn.load, gdzie <ścieżka> jest identyczna jak dla już ładowanych przez ten plik modułów. 6. Konfigurujemy udostępnienie pojedynczego repozytorium (proszę nie przepisywać komentarzy, gdyż czasami apache może się na nich wyłożyć!):
<Location /adres> DAV svn SVNPath $repos/$repozytorium AuthType Basic AuthName "SVN Repo" AuthUserFile $htpasswd Require valid-user </Location> #adres pod jakim będzie widoczne #repozytorium, nie musi mieć żadnego związku #z rzeczywistą nazwą repozytorium #włączenie svn #katalog na dysku gdzie znajduje się #repozytorium #uwierzytelnianie za pomocą loginu i hasła #nazwa okienka logowania #ścieżka do pliku z hasłami #wpuszczamy tylko poprawnie zalogowanych #użytkowników 7. Po zmianie pliku konfiguracyjnego należy zrestartować serwer apache. W wierszu poleceń należy wykonać polecenie: /etc/init.d/apache2 restart. Jeżeli wszystko zostało skonfigurowane poprawnie to serwer powinien wystartować bez problemów. Aby przetestować samo działanie repozytorium należy włączyć przeglądarkę WWW (w przypadku korzystania z trybu tekstowego polecam doinstalować przeglądarkę działającą w trybie tekstowym o nazwie links. Aby przejść do wprowadzania adresu należy nacisnąć g ) i w polu adresu wpisać url: http://localhost/adres. Jeżeli konfiguracja została wprowadzona poprawnie powinniśmy zostać zapytani o login i hasło, a po podaniu danych dowolnego spośród wprowadzonych wcześniej poleceniem htpasswd powinniśmy zobaczyć stronę o treści Revision 0: / pokazująca nasze puste repozytorium. 8. Udostępnianie wielu repozytoriów możliwe jest zdefiniowanie systemu tak, by konfiguracja poprzez jeden wpis obejmowała wiele repozytoriów, zarówno te obecnie istniejące jak i utworzone w przyszłości. Na potrzeby laboratorium niech to będzie utworzony wcześniej katalog $repos, w którym znajduje się właściwe repozytorium. W tym celu należy zmodyfikować odniesienie do katalogu na dysku z SVNPath $repos/$repozytorium na SVNParentPath $repos. W tym momencie każde odwołanie do adresu http://localhost/adres/$repozytorium spowoduje wczytanie podanego jako $repozytorium repozytorium. Jego nazwa musi być w tym wypadku taka sama jak nazwa zawierającego go katalogu, a adres to URL zdefiniowany w znaczniku Location w punkcie 4. Uwierzytelnianie użytkowników w przypadku każdego z tych repozytoriów odbywać się będzie na podstawie wspólnego, zdefiniowanego w punkcie 4. pliku $htpasswd. 9. Różnicowanie uprawnień w zależności od wybranego repozytorium możliwe jest oczywiście ograniczenie uprawnień użytkowników do korzystania z wybranych repozytoriów czy ich podkatalogów. Do rozwiązania uzyskanego w punkcie 6, wewnątrz znacznika Location należy dodać jeszcze jeden wpis: AuthzSVNAccessFile $accessfile Gdzie $accessfile to ścieżka do pliku tekstowego zawierającego reguły dostępu do repozytoriów. Najprostszy taki plik ma postać: [groups] admins = user1 grupa1 = user1,user2
grupa2 = user3,user4 [/] @admins = rw [$repozytorium:/] @grupa1 = rw @grupa2 = r Najpierw należy zdefiniować grupy użytkowników, nazwy grup mogą być dowolne, w przykładzie powyżej utworzono grupę admins oraz grupa1. Do grup należy przypisać użytkowników o loginach identycznych z tymi, jakie podaliśmy w pliku $htpasswd. Kolejnym krokiem jest przypisanie grupom uprawnień do konkretnych repozytoriów. Znacznik [/] oznacza wszystkie repozytoria, możliwe jest więc zdefiniowanie uprawnień dla pewnej grupy użytkowników do wszystkich repozytoriów. Dostęp do poszczególnych repozytoriów odbywa się za pomocą znaczników [$repozytorium:/], gdzie $repozytorium to nazwa katalogu (bez ścieżki) zawierającego dane repozytorium. Grupom można przypisywać uprawnienia do odczytu (r) lub odczytu i zapisu (rw)., możliwe jest również przypisanie uprawnień do podkatalogu w repozytorium za pomocą znacznika [$repozytorium:/sciezka/do/katalogu]. Mając tak skonfigurowany system można teraz dodać inne repozytoria po prostu tworząc ich katalogi wewnątrz katalogu $repos i inicjalizując je poleceniem svnadmin. 10. Pobranie kodu z repozytorium za pomocą wiersza poleceń w pierwszej kolejności spróbujemy pobrać, a następnie zmodyfikować i wysłać kod z repozytorium. W tym celu zainicjujmy lokalną kopię pobierając puste repozytorium do jakiegoś katalogu. W tym celu w wierszu poleceń przechodzimy do nowo utworzonego katalogu a następnie wykonujemy polecenie: svn checkout http://adres_servera/adres/$repozytorium <katalog> --username <użytkownik> Opcja <katalog> informuje narzędzie jaką część kodu w repozytorium chcemy pobrać. Jeżeli użyjemy tutaj. to pobrane zostanie całe repozytorium, jeżeli podamy jakąś inną wartość to pobrana zostanie zawartość tylko tego katalogu i jego podkatalogów. Następnie należy utworzyć jakiś kod źródłowy. Utwórzmy prosta aplikację Hello world w języku Java znajdującą się w pakiecie pakiet i klasie Klasa. Następnie za pomocą polecenia: svn add <katalog> zaznaczamy nowo utworzone pliki jako dodane do repozytorium. Pozostaje już tylko wysłać zmiany za pomocą polecenia: svn commit -m <opis zmian> Aby sprawdzić czy w repozytorium pojawiły się jakieś nowe pliki nie istniejące w naszej lokalnej kopii najlepiej wykonać polecenie
svn update Jeżeli teraz w przeglądarce WWW otworzymy adres wskazany w punkcie 6, to po zalogowaniu zobaczymy dodany katalog pakietu oraz znajdujący się w nim plik. 11. Ten punkt jest dodatkowy do Państwa wiadomości. Obsługa subversion za pomocą Netbeans do pracy z repozytorium nie jest oczywiście konieczne stosowanie wiersza poleceń. Większość edytorów kodu ma zaimplementowane wsparcie dla tego typu repozytorium. Podczas tych zajęć posłużymy się przykładem środowiska Netbeans. Aby zaimportować projekt z repozytorium należy kliknąć w menu: Versioning->Subversion- >Checkout. Pojawi się okienko jak na Rys. 2. Należy wpisać adres repozytorium oraz login (najlepiej inne niż używane w punkcie 8) i hasło użytkownika a następnie kliknąć Next. Na następnej stronie wybieramy ew. wersję czy katalog jaki ma być pobrany (zostawiamy puste pobrane zostanie całe repozytorium w najbardziej aktualnej wersji), oraz podajemy katalog, do którego mają być zapisane źródła domyślnie będzie to /home/<użytkownik>/netbeansprojects. Tutaj najlepiej dodać jeszcze jakiś katalog, np. /home/<użytkownik>/netbeansprojects/svn, by nowo pobrane źródła nie trafiły do katalogu z folderami innych projektów. Klikamy Finish. Netbeans pobierze pliki do wskazanego katalogu po czym zapyta nas, czy utworzyć na ich podstawie projekt klikamy Create project. Rys. 2: Podłączanie się do repozytorium Z listy typów projektów wybieramy Java Java project with existing sources i klikamy Next. Podajemy nazwę nowego projektu i klikamy Next. Na następnym ekranie przy polu Source package folders klikamy Add Folder po czym wskazujemy katalog użyty wcześniej (do którego zostały pobrane źródła z repozytorium). Klikamy Open a następnie Finish. 12. Wprowadzanie zmian oraz wysyłanie ich na serwer po modyfikacji pliku ze źródłami kolor odpowiedniej klasy zmieni się na niebieski a zawierający ją pakiet otrzyma ikonkę niebieskiego dysku. W ten sposób w Netbeans oznacza pliki zmodyfikowane. Nowo dodane pliki oznaczane są z kolei kolorem zielonym. Proszę zmodyfikować plik źródłowy a następnie kliknąć prawym klawiszem na pakiet i wybrać opcję Subversion Commit. W okienku dialogowym wprowadzamy opis zmian i klikamy Commit. Zmiany zostały wysłane na serwer. Można również wysłać kilka pakietów naraz
(zaznaczając wybrane trzymając shift lub ctrl) lub cały projekt, lecz w tym ostatnim przypadku należy pamiętać, że wysłane zostaną wszystkie ustawienia projektu, łącznie ze ścieżkami na dysku, które mogą nie być prawidłowe na innych komputerach. Po wysłaniu zmian zmodyfikowane/dodane pliki zostaną ponownie oznaczone kolorem czarnym a ikonka dysku zniknie. 13. Proszę dla sprawdzenia pobrać wysłany kod do katalogu synchronizowanego ręcznie za pomocą komend wiersza poleceń. Powinny zostać pobrane wprowadzone zmiany. 14. Rozwiązywanie konfliktów proszę zmodyfikować kod zarówno w repozytorium obsługiwanym przez Netbeans jak i tym, które obsługujemy z wiersza poleceń (jakieś inne modyfikacje) po czym najpierw wyeksportować zmiany w wierszu poleceń. Następnie klikamy prawym przyciskiem na zmodyfikowanym pakiecie i klikamy Subversion Commit. Netbeans zgłosi błąd, że nasza wersja jest niezgodna z tym, co znajduje się w repozytorium (Rys. 3). Rys. 3: Niezgodność z repozytorium Należy najpierw pobrać zawartość repozytorium i połączyć ją z naszymi zmianami. W tym celu klikamy prawym klawiszem na projekcie i wybieramy Subversion Update. Jeżeli zmiany są relatywnie proste narzędzie samo połączy obie wersje, należy jedynie odświeżyć widok otwierając ponownie dany plik z kodem źródłowym. Jeżeli okaże się, że narzędzie nie może samo podołać złączeniu zmian wyświetlone zostaną obie wersje wraz z różnicami i użytkownik będzie musiał ręcznie wykonać złączenia obu wersji. Zadanie do wykonania: Do realizacji zadania powinna wystarczyć karta sieciowa w trybie NAT by moc pobierać dane z Internetu. Jeżeli ktoś chce testować dostęp przez WWW czy z Netbenas z poziomu komputera rzeczywistego to należy dodać drugą kartę sieciową typu Host-only Adapter. UWAGA! W trakcie realizacji zadania należy zwrócić uwagę na prawa dostępu do katalogów. Serwer apache działa z poziomu użytkownika o nazwie www-data (grupa nazywa się tak samo) i takiemu użytkownikowi należy nadać uprawnienia do katalogów zawierających repozytorium i całej ścieżki do nich! Powtórka z systemów operacyjnych - polecenia:
chown nazwa_użytkownika[:nazwa_grupy] nazwa_katalogu [-R] zmiana właściciela i opcjonalnie grupy będącej właścicielem (-R rekurencyjnie) pliku lub katalogu chmod u+[rwx] nazwa_katalogu [-R] dodanie uprawnień dla właściciela pliku lub katalogu (ustawianego przez chmod, -R rekurencyjnie), można użyć dowolnej kombinacji znaków r (odczyt), w (zapis), x (wykonanie/wejście do katalogu) chmod g+[rwx] nazwa_katalogu [-R] dodanie uprawnień dla grupy chmod o+[rwx] nazwa_katalogu [-R] dodanie uprawnień dla całej reszty Jeżeli chcą państwo odebrać jakieś uprawnienia to należy zamiast znaku + w poleceniach użyć znaku -. 1. Uruchomić maszynę wirtualną, aktywować i skonfigurować poprzez DHCP kartę sieciową (tak jak na Laboratorium nr 3). Zainstalować serwer apache2 oraz narzędzie subversion i moduł svn do apache2 (należy tutaj wyłączyć instalację z CD tak jak na Laboratorium nr 3). Skonfigurować pojedyncze repozytorium z zachowaniem podstaw bezpieczeństwa czyli plików haseł NIE umieszczamy w repozytorium. Zaprezentować działanie poprzez WWW i za pomocą klienta z wiersza poleceń, przesłać jakieś pliki do repozytorium (punkty 1-7 oraz 10 instrukcji) 3 punkty 2. Zmodyfikować konfigurację tak, by za pomocą jednej konfiguracji możliwe było hostowanie wielu repozytoriów. Utworzyć 2 repozytoria w ten sposób i zabezpieczyć dostęp do nich tak, by jeden użytkownik miał prawo odczytu i zapisu w pierwszym oraz odczytu w drugim i każdym następnym utworzonym w przyszłości a drugi użytkownik prawo odczytu i zapisu w drugim repozytorium. Zaprezentować działanie poprzez WWW i za pomocą klienta z wiersza poleceń (punkty 8 i 9 instrukcji) 2 punkty. 3. Zadanie dodatkowe (można zdobyć dodatkowy punkt): Zabezpieczyć serwer apache umożliwiając połączenia przez protokół SSL. Uniemożliwić dostęp do repozytorium za pomocą połączenia nieszyfrowanego (podpowiedź: SSLRequireSSL). Zaprezentować działanie poprzez WWW.