Svnsync to jeden z wielu programów wchodzący w skład pakietu subversion. Służy do synchronizacji dwóch repozytoriów – pierwotnego i kopii. Ze względu na tę funkcjonalność narzędzie to idealnie może służyć do tworzenia kopii całego repozytorium na innym komputerze.
Mi się przydało w osobliwej sytuacji, gdzie do dyspozycji w firmie miałem „działowego” vps. Chciałem wprowadzić trac’a jako domyślny task manager dla wszystkich projektów z działu. Jednak repozytoria tych projektów znajdują się na innej maszynie, a dostanie się do nich wymusza otwarcie tunelu. Jednak obecna, stabilna wersja trac (0.11) nie obsługuje jeszcze zdalnego repozytorium, a administrator jest mega zajęty i nie ma czasu na moje widzi misie
Z pomocą przyszedł program svnsync.
Zasada jest bardzo prosta – inicjujemy na komputerze (hostującym kopię) projekt kopię :
svnadmin create /home/services/subversion/kopia cd /home/services/subversion/kopia find -type f | xargs chmod 666 find -type d | xargs chmod 777 chown -Rf svnuser:svn *
Dalej na komputerze kopii dodajemy nowego uzytkownika w svn, który będzie mial możliwość zapisywania plików w tym repozytorium. Najprościej:
htpasswd -nmb svnsync moje_haslo >> /etc/htpasswd/svn_dav
Następnie w katalogu /home/services/subversion/kopia/hooks należy dodać pliki:
start-commit
#!/bin/sh USER="$2" if [ "$USER" = "svnsync" ]; then exit 0; fi echo "Tylko użytkownik svnsync może dodawać nowe rewizje" >&2 exit 1
oraz plik pre-revprop-change
#!/bin/sh USER="$2" if [ "$USER" = "svnsync" ]; then exit 0; fi echo "Tylko użytkownik svnsync może dodawać nowe rewizje" >&2 exit 1
Następnie:
chmod 775 /home/services/subversion/kopia/hooks/start-commit chmod 775 /home/services/subversion/kopia/hooks/pre-revprop-change
Przeznaczenie tych plików? Sprawa prosta, kopia służy tak naprawdę tylko do odczytu. Nie chcę aby to repozytorium było robocze, ponieważ synchronizacja odbywa się tylko w jedną stronę. Udostępnienie kopii w formie roboczej doprowadziło by do powstania dwóch niespójnych repozytoriów.
Jest tylko jeden użytkownik tego repozytorium – svnsync, dzięki temu mam pewność, że nikt nie zaciągnie sobię tego repozytorium i nie będzie nic commit‘ował. W rezultacie uzyskam dokładną kopię repozytorium, na którym mi zależy.
Bardzo ważna uwaga! svnsync synchronizuje cały projekt, a nie jego rozgałęzienia. Nie możemy zatem synchronizować tylko wybranego katalogu.
Następnie musimy zainicjować synchronizację przez wywołanie polecenia svnsync z parametrem initialize. Jeśli w grę wchodzi kilka repozytoriów najlepiej napisać prosty skrypt np. taki:
#!/bin/sh PROJECTNAME_FROM="$1" PROJECTNAME_TO="$2" SVNSYNC=/usr/bin/svnsync FROM=https://host_oryginal/PROJECTNAME_FROM TO=https://host_kopia/$PROJECTNAME_TO SYNC_USER=svnsync SYNC_PASS=skomplikowane_haslo SOURCE_USER=uzytkownik_oryginalu SOURCE_PASS=haslo_uzytkownika_oryginalu $SVNSYNC initialize $TO $FROM --sync-username $SYNC_USER --sync-password $SYNC_PASS --source-username $SOURCE_USER --source-password $SOURCE_PASS & exit 0
Wtedy wywołanie takiego skryptu sprowadza się jedynie do:
svnsync_init oryginal kopia
Mi się przydał, bo synchronizowałem ok dziesięć projektów.
Nasuwa się dalej pytanie – jak synchronizować kopię z oryginałem?
Rozwiązań jest kilka. Można np. użyć crona, który co okręślony interval czasu odpalał by skrypt podobny do tego:
#!/bin/sh PROJECTNAME_TO="$1" SVNSYNC=/usr/bin/svnsync TO=https://host_kopia/$PROJECTNAME_TO SYNC_USER=svnsync SYNC_PASS=skomplikowane_haslo SOURCE_USER=uzytkownik_oryginalu SOURCE_PASS=haslo_uzytkownik_oryginalu $SVNSYNC --non-interactive sync $TO --sync-username $SYNC_USER --sync-password $SYNC_PASS --source-username $SOURCE_USER --source-password $SOURCE_PASS & exit 0 chmod 775 /home/services/subversion/kopia/hooks/svnsync_init
Polecenie svnsync z parametrem sync służy do synchronizowania repozytorium.
Wywołanie skryptu synchronizującego wyglądało by tak:
svnsync_sync kopia
Takie rozwiązanie jest jednak bardzo niewygodne. Poza tym, że dodatkowo co jakiś określony czas obciążamy maszynę kopię, to w dodatku zmiany w repozytorium pojawią się dopiero za chwilę (np. za 5 minut). Ja nie mogę czekać tak długo. Przypominam, że zależy mi na pracy z trac‘iem. Każdy commit musi być rejestrowany automatycznie. Poza tym w moim przypadku, aby wywolać polecenie svn up, muszę otworzyć tunel. Mogę to zrobić jedynie z ręki i nie mógłbym wtedy doprowadzić do zamknięcia tego tunelu.
Z pomocą znów przychodzą hooks na serwerze oryginał. W katalogu /home/services/subversion/oryginal/hooks edytujemy plik:
post-commit
#!/bin/sh SVNSYNC=/usr/bin/svnsync TO=https://host_kopia/kopia SYNC_USER=svnsync SYNC_PASS=skomplikowane_haslo SOURCE_USER=uzytkownik_oryginal SOURCE_PASS=haslo_uzytkownika_oryginal $SVNSYNC --non-interactive sync $TO --sync-username $SYNC_USER --sync-password $SYNC_PASS --source-username $SOURCE_USER --source-password $SOURCE_PASS & exit 0 chmod 775 /home/services/subversion/kopia/hooks/post-commit
Opcja –non-interactive spowoduje, że w razie niepowodzenia synchronizacji użytkownicy pracujący przy repozytrium nie zobaczą żadnego błędu podczas commit‘a, jeśli takowy miałby wystąpić. W praktyce takie rozwiązanie działa błyskawicznie i bezbłędnie.
Podsumowując, osiągnąłęm swój cel. Na maszynie kopia mam zainstalowanego trac‘a, który bazuje na repozytorium znajdujące się na maszynie oryginal. W praktyce Każdy commit w repozytorium oryginal spowoduje zarejestrowanie zmiany w trac’u.
Super od teraz możemy zarządzać projektami
Comments
Leave a comment Trackback