KIELMAS.COM Kielmas Jarosław

Blog głównie o programowaniu

Browsing Posts in Technologie IT

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 :)

W środę, 28 kwietnia 2010 na wydziale MFI UG odbył się wykład zatytułowany „Critical testing process”, który wygłosił pan Wojciech Jaszcz – Dyrektor Departamentu Zapewnienia Jakości, Wdrożeń i Analiz w firmie Acxiom

Mimo konkretnych korków na obwodnicy, spowodowanych naprawą nawierzchni (przynajmniej 3 zwężenia drogi na odcinku 10 km – seek!) udało mi się dojechać na czas.  Razem z matipl tworzyliśmy niewielką grupę słuchaczy.

Temat bardzo ciekawy i na pewno nie został wyczerpany w ciągu półtorej godziny  – został raczej wprowadzony. Pan Wojtek  na wstępie przedstawił 12 fundamentalnych zasad testowania aplikacji. W ich skład wchodzi m.in. Plan, Prepare, Perform, Perfect, Develop team … (niestety tylko tyle udało mi się zapamiętać). Każde z tych zasad zostało omówione na konkretnym przykładzie, co dodatkowo ułatowiło zrozumienie tematu.

Podejście pana Wojtka do tematu było czysto praktyczne, a tym samym w małym stopniu  teoretyczne i oparte o problemy, jakie napotkał pracując w zawodzie. Abstrahując od tematu – takie wykłady na studiach z pewnością zaciekawiły by niejednego studenta, który wyniósł by przynajmniej częsciowe wyobrażenie nt. problemów  i sposobów ich rozwiązywania w przyszłej karierze.

Wykład bardzo mi się podobał. Dzięki niemu zdałem sobie sprawę, jak ważne są testy aplikacji i jak bardzo kosztowne jest zaniedbanie testowania przed wydaniem release (mowa tu np.  o około 60 miliardach dolarów rocznie, jakie wydawane są przez amerykańskie firmy, których soft okazał się trefny).  Zdałem sobie także sprawę, że większość projektów, w których uczestniczyłem nie została przetestowana tak, jak powinna być.

Podobało mi się także stwierdzenie wypowiedziane przez pana Wojtka – „o testy jednostkowe dba programista i musi je wykonać. Koniec, Kropka!! „. Także, nie bez powodu, w przyborniku matipl znalazła się pozycja PHPUnit.

Wykład bardzo ciekawy, udany, dużo się dowiedziałem i już czekam na kolejne tego typu spotkania.

Matipl powiadomił o najnowszej wersji ZF 1.10.4 i wskazał na wiele poprawek poprawiającaych bezpieczeństwo frameworka. Po aktualizacji i dodaniu do repo  można się przekonać ile plików zostało dotkniętych poprawkami. Oto wynik svn status

M       Zend/File/Transfer/Adapter/Http.php
M       Zend/File/Transfer/Adapter/Abstract.php
M       Zend/File/Transfer.php

M       Zend/Dom/Query.php

M       Zend/Log/Filter/Abstract.php
M       Zend/Log/Filter/Message.php
?       Zend/Log/Writer/ZendMonitor.php

M       Zend/Form.php

M       Zend/Dojo/View/Helper/Dojo/Container.php

M       Zend/Loader.php

?       Zend/Service/WindowsAzure
?       Zend/Service/LiveDocx.php
?       Zend/Service/DeveloperGarden
?       Zend/Service/LiveDocx
M       Zend/Service/Amazon/Item.php
M       Zend/Service/Amazon/Offer.php
M       Zend/Service/Amazon/Sqs.php
M       Zend/Service/Flickr.php

M       Zend/Soap/Wsdl/Strategy/ArrayOfTypeComplex.php

?       Zend/Feed/Writer.php
?       Zend/Feed/Pubsubhubbub
?       Zend/Feed/Writer
?       Zend/Feed/Pubsubhubbub.php
?       Zend/Feed/Reader/Collection.php
?       Zend/Feed/Reader/Collection
?       Zend/Feed/Reader/Feed/Atom

?       Zend/Config/Writer/FileAbstract.php

?       Zend/Pdf/Filter/RunLength.php

?       Zend/Pdf/Annotation/Markup.php

M       Zend/Pdf/Resource/Font/Extracted.php

M       Zend/Pdf/Element/String.php

?       Zend/Http/Response
M       Zend/Http/Cookie.php
M       Zend/Http/Client.php
?       Zend/Http/Client/Adapter/Stream.php
M       Zend/Http/Client/Adapter/Proxy.php
M       Zend/Http/Client/Adapter/Socket.php

M       Zend/Validate.php

M       Zend/Ldap/Attribute.php
M       Zend/Ldap/Ldif/Encoder.php

M       Zend/Oauth/Http/Utility.php
M       Zend/Oauth/Client.php

M       Zend/CodeGenerator/Php/Class.php

M       Zend/Controller/Request/Http.php
?       Zend/Controller/Action/Helper/Cache.php
M       Zend/Controller/Response/Abstract.php

M       Zend/Paginator/Adapter/Null.php

M       Zend/Db/Adapter/Sqlsrv.php
M       Zend/Db/Statement/Pdo/Oci.php
M       Zend/Db/Table/Row/Abstract.php
M       Zend/Db/Table/Abstract.php

M       Zend/Cache.php

?       Zend/Currency/CurrencyInterface.php

M       Zend/TimeSync/Ntp.php

M       Zend/Translate/Adapter/Csv.php
M       Zend/Translate/Adapter/Tmx.php
M       Zend/Translate/Adapter.php

M       Zend/Memory.php

M       Zend/Barcode/Object/Code39.php

M       Zend/Locale/Data.php
M       Zend/Locale/Math.php
M       Zend/Locale/Format.php

M       Zend/Markup/Renderer/RendererAbstract.php
M       Zend/Markup/Renderer/Html.php

M       Zend/Markup/Parser/Bbcode.php

M       Zend/Auth/Adapter/Ldap.php
M       Zend/Log.php

?       Zend/View/Helper/Currency.php
M       Zend/View/Helper/FormElement.php

M       Zend/View/Abstract.php

M       Zend/Date/DateObject.php

M       Zend/Tool/Project/Profile/Resource/Container.php
M       Zend/Tool/Project/Profile/FileParser/Xml.php

?       Zend/Tool/Project/Context/Zf/LayoutScriptFile.php
?       Zend/Tool/Project/Context/Zf/LayoutScriptsDirectory.php
?       Zend/Tool/Project/Context/Zf/AbstractClassFile.php
?       Zend/Tool/Project/Context/Zf/DocsDirectory.php
M       Zend/Tool/Project/Context/Zf/ApplicationConfigFile.php
M       Zend/Tool/Project/Context/Zf/HtaccessFile.php
M       Zend/Tool/Project/Context/Zf/ApplicationDirectory.php
M       Zend/Tool/Project/Context/Zf/DbTableFile.php
M       Zend/Tool/Project/Context/Zf/ZfStandardLibraryDirectory.php
M       Zend/Tool/Project/Context/Filesystem/File.php
M       Zend/Tool/Project/Context/System/ProjectProfileFile.php

M       Zend/Tool/Project/Profile.php
?       Zend/Tool/Project/Provider/DbTable.php
?       Zend/Tool/Project/Provider/Application.php
?       Zend/Tool/Project/Provider/Layout.php
?       Zend/Tool/Project/Provider/DbAdapter.php
M       Zend/Tool/Project/Provider/Action.php
M       Zend/Tool/Project/Provider/Model.php
M       Zend/Tool/Project/Provider/Controller.php
M       Zend/Tool/Project/Provider/Module.php
M       Zend/Tool/Project/Provider/Project.php

?       Zend/Tool/Framework/Metadata/Attributable.php
?       Zend/Tool/Framework/System/Provider/Config.php
?       Zend/Tool/Framework/Loader/Interface.php
?       Zend/Tool/Framework/Loader/BasicLoader.php
M       Zend/Tool/Framework/Loader/IncludePathLoader.php

?       Zend/Tool/Framework/Client/Manifest.php
?       Zend/Tool/Framework/Client/Console/ResponseDecorator/AlignCenter.php
?       Zend/Tool/Framework/Client/Console/ResponseDecorator/Blockize.php
?       Zend/Tool/Framework/Client/Console/ResponseDecorator/Indention.php
M       Zend/Tool/Framework/Client/Abstract.php

M       Zend/Mail/Protocol/Abstract.php

M       Zend/Mail/Transport/Sendmail.php

?       Zend/Queue/Adapter/Db/queue_sqlite.sql

?       Zend/Filter/Null.php
?       Zend/Filter/Compress.php
?       Zend/Filter/Decompress.php
?       Zend/Filter/Compress
?       Zend/Filter/Boolean.php
M       Zend/Filter/PregReplace.php
M       Zend/Filter/HtmlEntities.php
M       Zend/Filter/StripTags.php
M       Zend/Filter/StringToLower.php
M       Zend/Filter/Word/CamelCaseToSeparator.php
M       Zend/Filter/Inflector.php
M       Zend/Filter/StringToUpper.php

M       Zend/Reflection/File.php

M       Zend/Measure/Abstract.php

M       Zend/Form/Element.php
M       Zend/Form/Decorator/Fieldset.php
M       Zend/Form/Decorator/Abstract.php
M       Zend/Form/Decorator/Label.php

?       Zend/XmlRpc/Generator
M       Zend/XmlRpc/Value.php
M       Zend/XmlRpc/Value/Double.php
M       Zend/XmlRpc/Value/Array.php
M       Zend/XmlRpc/Value/Struct.php
M       Zend/XmlRpc/Value/Scalar.php

M       Zend/Wildfire/Channel/HttpHeaders.php

M       Zend/Loader/PluginLoader.php

M       Zend/Oauth.php

M       Zend/Currency.php

M       Zend/Translate.php

M       Zend/Text/MultiByte.php

M       Zend/Exception.php

M       Zend/Locale.php

?       Zend/Validate/Callback.php
?       Zend/Validate/CreditCard.php
?       Zend/Validate/PostCode.php
?       Zend/Validate/Isbn.php
M       Zend/Validate/File/MimeType.php
M       Zend/Validate/File/IsCompressed.php
M       Zend/Validate/File/ExcludeMimeType.php
M       Zend/Validate/File/IsImage.php
M       Zend/Validate/File/Count.php
M       Zend/Validate/EmailAddress.php
M       Zend/Validate/Abstract.php
M       Zend/Validate/Float.php
M       Zend/Validate/Barcode.php
M       Zend/Validate/Iban.php
?       Zend/Validate/Barcode/Royalmail.php
?       Zend/Validate/Barcode/Sscc.php
?       Zend/Validate/Barcode/Ean8.php
?       Zend/Validate/Barcode/Postnet.php
?       Zend/Validate/Barcode/Upce.php
?       Zend/Validate/Barcode/Identcode.php
?       Zend/Validate/Barcode/AdapterInterface.php
?       Zend/Validate/Barcode/Gtin12.php
?       Zend/Validate/Barcode/Code25interleaved.php
?       Zend/Validate/Barcode/AdapterAbstract.php
?       Zend/Validate/Barcode/Gtin13.php
?       Zend/Validate/Barcode/Gtin14.php
?       Zend/Validate/Barcode/Ean12.php
?       Zend/Validate/Barcode/Code39ext.php
?       Zend/Validate/Barcode/Code93ext.php
?       Zend/Validate/Barcode/Ean14.php
?       Zend/Validate/Barcode/Issn.php
?       Zend/Validate/Barcode/Ean18.php
?       Zend/Validate/Barcode/Code25.php
?       Zend/Validate/Barcode/Intelligentmail.php
?       Zend/Validate/Barcode/Planet.php
?       Zend/Validate/Barcode/Ean2.php
?       Zend/Validate/Barcode/Code39.php
?       Zend/Validate/Barcode/Code93.php
?       Zend/Validate/Barcode/Itf14.php
?       Zend/Validate/Barcode/Ean5.php
?       Zend/Validate/Barcode/Leitcode.php
?       Zend/Validate/Barcode/Upca.php
M       Zend/Validate/Regex.php
M       Zend/Validate/Sitemap/Loc.php
M       Zend/Validate/Sitemap/Priority.php
M       Zend/Validate/Sitemap/Changefreq.php
M       Zend/Validate/Sitemap/Lastmod.php
M       Zend/Validate/Hostname.php
M       Zend/Validate/Digits.php

M       Zend/Amf/Response.php
M       Zend/Amf/Parse/Serializer.php
M       Zend/Amf/Parse/Amf0/Serializer.php
M       Zend/Amf/Parse/Amf0/Deserializer.php
M       Zend/Amf/Parse/Amf3/Serializer.php
M       Zend/Amf/Parse/Amf3/Deserializer.php
M       Zend/Amf/Server.php
M       Zend/Amf/Util/BinaryStream.php

?       Zend/Application/Resource/Dojo.php
?       Zend/Application/Resource/Cachemanager.php
?       Zend/Application/Resource/Multidb.php
?       Zend/Application/Resource/Log.php
?       Zend/Application/Resource/Mail.php
M       Zend/Application/Resource/View.php
M       Zend/Application/Resource/Frontcontroller.php
M       Zend/Application/Resource/Layout.php
M       Zend/Application/Resource/Translate.php
M       Zend/Application/Resource/Locale.php
M       Zend/Application/Resource/Navigation.php
M       Zend/Application/Resource/Router.php
M       Zend/Application/Resource/Session.php
M       Zend/Application/Resource/Db.php
M       Zend/Application/Resource/Modules.php
M       Zend/Application/Bootstrap/Bootstrap.php
M       Zend/Application/Bootstrap/BootstrapAbstract.php

?       Zend/Cache/Manager.php
?       Zend/Cache/Frontend/Capture.php
?       Zend/Cache/Backend/BlackHole.php
?       Zend/Cache/Backend/Static.php
M       Zend/Cache/Backend/File.php
M       Zend/Cache/Backend/Test.php
M       Zend/Cache/Backend/TwoLevels.php
M       Zend/Cache/Backend/Memcached.php
M       Zend/Cache/Backend.php
M       Zend/Cache/Core.php

M       Zend/Date.php

M       Zend/Search/Lucene.php
M       Zend/Search/Lucene/Search/QueryParser.php
M       Zend/Search/Lucene/Document/Html.php

M       Zend/Mail.php

M       Zend/Filter.php

M       Zend/Version.php

Jak widać jest to długa lista zmian, dotyczące główne komontenty frameworka.

W telewizji można zobaczyć reklamę, która promuje IE8 jako przeglądarke, która umożliwia bezpieczne przeglądanie stron www, transakcje bankowe, … itd.

NSS Labs opublikowało raport, który pokazuje, że aż o 56 procent ogólnej ochrony przeglądarka Internet Explorer 8 wyprzedza konkurencyjne produkty Safari 4 i Firefox 3.5.  Microsoft ma zatem podstawy do zachwycania się swoim produktem.

Jednak czytając publikacje podobne  do tej wdaję się, że cieżko zaufać jej twórcom, na tyle aby używać jej jako domyślnej przeglądarki. Moim zdaniem cała ta kampania reklamowa ma wygasić incydent sprzed około roku, kiedy to prezes Microsoft radził, aby do momentu ukazania się odpowiedniej aktualizacji nie korzystać z IE.

Osobiście, w pracy jak i na codzień, korzystam z Opery oraz FF.