3 lutego 2008

Artifactory, czyli prywatne repozytorium Maven 2

Stało się, w końcu nie wytrzymałem i wziąłem się poważnie za prace nad swoim warsztatem programistycznym. Red Hat Developer Studio zirytowało mnie już wystarczająco, przesiadłem się więc na Maven 2! Muszę powiedzieć, że póki co jestem zachwycony. Zapewne z czasem przyjdą też poważne trudności i rozczarowania, ale na razie jest super, tym bardziej, że od razu zacząłem ostro i mogę zachwycać się takimi rzeczami jak chociażby integracja poprzez repozytorium kodu z serwerem automatycznego budowania (ang. Continuous Integration Server). Szybko jednak stwierdziłem, że aby sprawnie zrealizować przy pomocy Maven 2 nie trywialny projekt niezbędna jest instalacja prywatnego repozytorium. Dzisiejszy artykuł poświęcony jest właśnie temu tematowi – repozytoriom Maven, a w szczególności instalacji i konfiguracji repozytorium Artifactory.

Mam jakieś takie zamiłowanie do opisywania tematów od podstaw, zatem zacznę od paru zdań na temat repozytoriów Maven 2. Przede wszystkim, repozytorium może być zdalne, albo lokalne. Repozytorium lokalne jest to swego rodzaju pamięć podręczna rezydująca na stacji roboczej, na której uruchamiany jest klient Maven’a. Jest to po prostu struktura katalogów na naszym komputerze przechowująca biblioteki pobrane z repozytoriów zdalnych. Repozytoria zdalne dzielą się, ogólnie rzecz biorąc, na repozytoria publiczne i prywatne. Repozytoria publiczne to te udostępnione w Internecie i umożliwiające pobieranie zależności bez konieczności uwierzytelnienia się, po prostu dla każdego. Repozytorium prywatne różni się od publicznego tym, że jest dedykowane dla pewnej organizacji lub projektu a dostęp do niego jest chroniony.

Wyobraźmy sobie, że tworzymy projekt Maven 2 składający się z wielu modułów powiązanych wzajemnymi zależnościami. Jeśli moduł A potrzebuje jako zależności modułu B to deklarujemy to w pliku pom.xml modułu A i to powinno wystarczyć. W rzeczy samej, wystarczy, ale tylko pod warunkiem, że mamy do dyspozycji repozytorium prywatne, które przechowuje i udostępnia moduły tego projektu. No chyba, że jesteśmy jedynym programistą zaangażowanym w projekcie i wystarczy nam współdzielenie poprzez repozytorium lokalne, ale jest to przypadek skrajny i nieinteresujący.

Zaczynamy od pobrania Artifactory. W chwili pisania tego artykułu najnowszą wersją jest 1.2.5 i to właśnie tej wersji użyłem dla swojej instalacji. Artifactory to aplikacja WWW, którą uruchamiamy w kontenerze serwletów (ang. servlet container). Dokumentacja Artifactory mówi o dwóch opcjach instalacji: jedną jest uruchomienie na wbudowanym kontenerze Jetty a inną na dowolnym serwerze zewnętrznym implementującym odpowiednie standardy, np. na serwerze Tomcat. Ja wybrałem instalację na serwerze Tomcat 6.0.14. Sama instalacja jest procesem trywialnym, oczywiście o ile nie natrafi się na poza standardowe trudności. Ja nie natrafiłem i w zasadzie nie mam nic do dodania względem tego, co jest w dokumentacji Artifactory. Pobrane archiwum .zip rozpakowujemy w dowolnej lokalizacji, kopiujemy plik /webapps/artifactory.war do podkatalogu webapps katalogu domowego serwera Tomcat i ustawiamy zmienną artifactory.home tak aby wskazywała na katalog domowy instalacji Artifactory. To ostatnie możemy zrealizować na wiele sposobów, jednym z nich jest przypisanie zmiennej środowiskowej JAVA_OPTS lub CATALINA_OPTS wartości '-Dartifactory.home=<katalog główny Artifactory>'. To tyle, przechodzimy do konfiguracji. W tym celu edytujemy plik konfiguracyjny Artifactory /etc/artifactory.config.xml. Tutaj definiujemy repozytoria, proces tworzenia automatycznych kopii bezpieczeństwa, konfigurujemy proxy oraz co w tej chwili najważniejsze, tutaj deklarujemy, że nasze repozytorium jest rzeczywiście prywatne. Prywatne w tym sensie, że nie jest możliwy anonimowy, nie autoryzowany dostęp. Plik ten zawiera pewną domyślną konfigurację i nie musimy zmieniać zupełnie nic żeby aplikacja po prostu działała, ale powinniśmy wykonać ten jeden mały krok polegający na od komentowaniu (albo dodaniu, jeśli go niema) elementu:

<anonDownloadsAllowed>false</anonDownloadsAllowed>

Spowoduje to jak można się domyślić, że nie będzie możliwy anonimowy, nie autoryzowany dostęp do naszych zasobów. Warte odnotowania jest jeszcze to, że Artifactory dzieli repozytoria na lokalne (element localRepositories) i zdalne (element remoteRepositories). Repozytoria zdalne to częściowe kopie repozytoriów publicznych, punkt pośredni dla pobierania bibliotek a repozytoria lokalne to te, których Artifactory jest – nazwijmy to – właścicielem i administratorem. To by było na tyle jeśli chodzi o wstępną konfigurację, możemy uruchomić serwer i obejrzeć konsolę administracyjną. Uruchamiamy więc przeglądarkę, nawigujemy pod adres http://localhost:8080/artifactory i logujemy się używając identyfikatora 'admin' oraz domyślnego hasła 'password'. Musimy teraz utworzyć jakiegoś użytkownika na potrzeby klienta Maven i nadać mu uprawnienia do odczytu (rola Reader) oraz, co ważne, również do zapisu (rola Deployer) do repozytoriów. Później wyjaśnię, dlaczego. Poniżej prezentuje mój ekran konfiguracji dostępu.




Pozostała jeszcze konfiguracja klienta Maven 2. Po pierwsze, musimy Maven’owi dostarczyć identyfikator i hasło użytkownika Artifactory. W tym celu edytujemy plik konfiguracyjny /.m2/settings.xml. Dodajemy tu następujący fragment:

<servers>
<server>
<id>central</id>
<username>maven</username>
<password>passwd</password>
</server>
</servers>

Komentarza wymaga wartość elementu id. Jest to identyfikator serwera, do którego będziemy się następnie odwoływać w pliku pom.xml i może to być dowolna nazwa z tym, że akurat 'central' jest wartością specjalną, ale o tym za chwile. Edytujmy teraz plik pom.xml naszego projektu i umieśćmy tam następujący fragment:

<repositories>
<repository>
<id>central</id>
<url>http://localhost:8080/artifactory/repo</url>
</repository>
</repositories>

Ważne jest, aby element id miał tę samą wartość, co element id, dla serwera zdefiniowanego przed chwilą w pliku /.m2/settings.xml. Dodatkowo, jeśli wartość ta to 'central' to repozytorium to zasłoni repozytorium główne Maven’a. Co to oznacza? Oznacza to tyle, że wszelkie zależności Maven będzie rozwiązywał z użyciem naszego repozytorium Artifactory, które z kolei nie mogąc znaleźć odpowiednich zasobów w swoich repozytoriach lokalnych będzie ich wyszukiwało korzystając ze zdefiniowanych repozytoriów zdalnych. W takim wypadku Artifactory pobierze wpierw zależność z repozytorium zdalnego, doda ją do swojego repozytorium lokalnego i dopiero zwróci do klienta Maven inicjalizującego operację. W tym momencie powinno już być jasne, dlaczego użytkownik Artifactory wykorzystywany przez klienta Maven powinien mieć prawo do zapisu do repozytoriów. Gdyby tego prawa nie miał, nie było by możliwe pobieranie za pośrednictwem Artifactory zasobów z repozytoriów publicznych, nie było by bowiem możliwe umieszczenie artefaktu w repozytorium pośredniczącym. Pozostaje jeszcze wykonać test. W tym celu zdefiniujmy zakąś zależność od biblioteki dostępnej w repozytorium publicznym a nie obecnej jeszcze w naszym repozytorium lokalnym i uruchommy Maven’a. Jeśli wszystko jest dobrze biblioteka powinna być – oprócz tego, że pobrana – widoczna w drzewie repozytoriów Artifactory. Oto przykładowy widok:


4 komentarze:

Koziołek pisze...

Witam,

trochę to przekombinowane, ale wynika to z faktu, że pokazane było na localhost. Od siebie dodam, że rozwiązanie to znacznie lepiej sprawdza się gdy mamy np. sieć firmową i chcemy ograniczyć ruch na łączu. Programiści pobierają wtedy pakiety z sieci wewnętrznej, która jest co pewien czas, i co ważne tylko dla jednego użytkownika, aktualizowana. W połączeniu z np. lundbuildem niezastąpione do ograniczania ruchu na łączach.
pozdrawiam

Mariusz Lipiński pisze...

Witam,

to że w treści artykułu używałem 'localhost' a nie np. '<ip serwera>' to niczego nie zmienia. Ciekaw jestem co masz na myśli mówiąc o "przekombinowaniu". Co masz na myśli?

Koziołek pisze...

Przez przekombinowanie rozumiem właśnie ten "localhost". Samo rozwiązanie też jest taie sobie jeżeli jeseś samotnym developerem. Hm... Zastanawia mnie jeszcze to czy istnieje jakieś rozwiązanie oparte o niejavowe technologie.

Anonimowy pisze...

Dzięki. Artykuł bardzo mi pomógł. Od siebie dorzucę instrukcję upgradeu artifactory z wersji 1.2.5 do wersji 1.2.5u1.


Instrukcja opublikowana przez jfrog.org po prostu nie działa (-: Pozdrawiam