Development z Zapomnianej Strony

..:: Paweł Hofman .NET Portal ::..

Kolejny dzień, kolejny problem z serii, “bo coś jest zepsute u podstaw” konfiguracji systemu… Zawczasu ostrzegam, że wpis ten jest wybitnie rozwlekły i nie jest przeznaczony dla osób niecierpliwych.

Zatem po kolei. Będąc zafascynowany “nowymi” rozwiązaniami, postanowiłem w ramach testów uruchomić przykłady z pakietu CometD i zapoznać się nieco z protokołem Bayeux (zainteresowanych tematem odsyłam do dokumentacji projektu). Oczywiście nic prostszego - wchodzimy na stronę projektu, pobieramy odpowiednie źródła, wypakowujemy CometD i uruchamiamy Jetty, które instaluje w sobie odpowiednie rozszerzenie. Wszystko bardzo ładnie w kilku zdaniach opisane jest tutaj.

Jakież wyrazy cisną nam się na usta, gdy ściągane są kolejne pakiety idące już prawie w gigabajty (do Javy, Apache, Maven2, itp…). Mija w końcu to niesłychanie długie 20 minut i oczom naszym ukazuje się Jetty w pełnej krasie. Ostrzegam, że jeszcze nawet nie zaczęliśmy grzebać w naszym testowym Debianie, a przecież chwilkę temu pobraliśmy najnowsze wersje całego oprogramowania na świecie.

~/cometd-2.0.0/cometd-demo$ mvn jetty:deploy-war
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'jetty'.
[INFO] ------------------------------------------------------------------------
[INFO] Building CometD :: Demo
[INFO] task-segment: [jetty:deploy-war]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing jetty:deploy-war
[INFO] [enforcer:enforce {execution: enforce-plugin-versions}]
[INFO] [jetty:deploy-war]
[INFO] Configuring Jetty for project: CometD :: Demo
[INFO] Context path = /
[INFO] Tmp directory = /home/pawel/cometd-2.0.0/cometd-demo/target/tmp
[INFO] Web defaults = org/eclipse/jetty/webapp/webdefault.xml
[INFO] Web overrides = none
[INFO] Starting jetty 7.1.5.v20100705 ...
2010-09-05 01:29:34.971:INFO::jetty-7.1.5.v20100705
2010-09-05 01:29:37.803:WARN::EXCEPTION
java.lang.NullPointerException
    at javax.naming.spi.NamingManager.getPlusPath(libgcj.so.90)
    at javax.naming.spi.NamingManager.getStateToBind(libgcj.so.90)
    at org.eclipse.jetty.jndi.NamingContext.bind(NamingContext.java:337)
    at org.eclipse.jetty.jndi.NamingContext.bind(NamingContext.java:415)
    at org.eclipse.jetty.jndi.java.javaRootURLContext.(javaRootURLContext.java:78)
    at java.lang.Class.initializeClass(libgcj.so.90)
    at org.eclipse.jetty.jndi.java.javaURLContextFactory.getObjectInstance(javaURLContextFactory.java:63)
    at javax.naming.spi.NamingManager.getURLContext(libgcj.so.90)
    at javax.naming.spi.NamingManager.getURLContext(libgcj.so.90)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(libgcj.so.90)
    at javax.naming.InitialContext.lookup(libgcj.so.90)
    at org.eclipse.jetty.plus.webapp.EnvConfiguration.createEnvContext(EnvConfiguration.java:202)
    at org.eclipse.jetty.plus.webapp.EnvConfiguration.preConfigure(EnvConfiguration.java:62)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:378)
    at org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:114)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
    at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:165)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:162)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
    at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:165)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
    at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:92)
    at org.eclipse.jetty.server.Server.doStart(Server.java:242)
    at org.mortbay.jetty.plugin.JettyServer.doStart(JettyServer.java:67)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:437)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:377)
    at org.mortbay.jetty.plugin.JettyRunWarMojo.execute(JettyRunWarMojo.java:68)
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:451)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:558)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:512)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:482)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:330)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:291)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:287)
    at java.lang.reflect.Method.invoke(libgcj.so.90)
    at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
    at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
    at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:375)

A później jest już prościej, bo co sekundę wyskakuje wyjątek (co zdecydowanie lepiej rzuca się w oczy):

2010-09-05 01:38:42.200:WARN::EXCEPTION java.lang.ClassCastException: gnu.java.nio.ServerSocketChannelImpl cannot be cast to java.nio.channels.SocketChannel
    at org.eclipse.jetty.io.nio.SelectorManager$SelectSet.doSelect(SelectorManager.java:708)
    at org.eclipse.jetty.io.nio.SelectorManager.doSelect(SelectorManager.java:195)
    at org.eclipse.jetty.server.nio.SelectChannelConnector.accept(SelectChannelConnector.java:134)
    at org.eclipse.jetty.server.AbstractConnector$Acceptor.run(AbstractConnector.java:793)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:436)
    at java.lang.Thread.run(libgcj.so.90)

   

Jednym słowem czad!

No niby prosty przykład, a ile radości. Cóż, znowu ktoś zawinił. Tym bardziej ciekawe jest kto oraz że na forum projektu milczą o tym błędzie, jakby się wszyscy pod ziemię zapadli. Podpowiem, że projekty (CometD oraz sam Jetty) dostępne sąt od kilku ładnych lat i na pewno ktoś by się z tym problemem zetknął. Chyba nie jestem aż takim szczęściarzem. A może jednak to jest jakaś niszowa przypadłość? Bynajmniej. Troszkę szperania i co się okazuje. Otóż ani PATH ani JAVA_HOME nie pokazują lokalizacji JVM (Java Virtual Machine). Dokumentacja do Jetty mówi o tym wyraźnie. Ustawiamy ścieżkę do /usr/lib/jvm/java-1.5.0-gcj-xxx i wszystko powinno ruszyć. Teoretycznie. W praktyce, dostajemy dokładnie ten sam błąd. No jakoś się całe środowisko pokumało, że tylko jedna wersja Javy była zainstalowana i nawet bez JAVA_HOME udało się ją załadować. No to może jeszcze inaczej, może gdzieś, jakiś przełącznik, jakaś aktualizacja, patch rejestru (dobra to nie Windows), symlink? wrr, cokolwiek.

Otóż nie. To, co zazwyczaj okazuje się poprawne, zazwyczaj też siedzi na samym szarym końcu rozwiązań i ostatnie wpada do głowy. Cały JVM jest do wyrzucenia :) No bo przecież GNU Java nie jest zgodna z Sun Java (tu wstaw dowolną wersję), bo i po co? Jakichże to kolorów nabiera wtedy życie…

Tak, ale instalacja oryginalnej ‘sunowskiej’ Javy też nie jest wcale taka prosta. Aby uzyskać dostęp do wersji Javy (Sun JDK 1.5 i JDK 1.6), niezbędny jest na początku dodatkowy wpis w konfiguracji apt-get. Te JDK-i oznaczone są bowiem jako “non-free” i musimy zaakceptować dodatkową licencję zanim będziemy mogli z nich skorzystać.

  • Dopisujemy więc na końcu pliku konfiguracyjnego apt-get (/etc/apt/sources.list) następującą linijkę:

deb http://ftp.debian.org/debian lenny main contrib non-free

  • Odświeżamy listę dostępnych pakietów:

apt-get update

  • Instalujemy Javę (kawę i kolejne 20 min mamy już tym razem w pogotowiu):

apt-get install sun-java6-jdk

apt-get install sun-java5-jdk

  • Na koniec, ustawiamy ją jako domyślną w systemie:

update-java-alternatives -s java-6-sun
echo 'JAVA_HOME="/usr/lib/jvm/java-6-sun"' | tee -a /etc/environment

  • Gotowe! Uruchamiamy ponownie skrypt Maven, który uruchamia Jetty i instaluje w nim CometD. Tym razem z powodzeniem pod adresem http://localhost:8080/ mamy już działające przykłady i użycie Bayeux! Nic dodać nic ująć.

Jednak wieczór można uznać za udany. Szkoda tylko, że nie to mi go skradło, na co chciałem go przeznaczyć…

Dziękuję za uwagę.



Kiedy budzisz się pewnego dnia i od początku coś ci się nie układa. Nie wiesz do końca, o co chodzi, ale niektóre rzeczy dwoją i troją ci się w oczach. To jeszcze nie dowód na to, żeby odstawić mocniejsze trunki! To po prostu Visual Studio 2010 ześwirowało!

U mnie wyglądało to tak, że nie działał Backspace, Control i inne specjalne klawisze, zaś sam interfejs prezentował się tak, że każdy element menu i paska narzędziowego był zduplikowany kilka razy w pozornie losowych miejscach:

VisualStudio 2010 - podwójne menu 

VisualStudio2010 - podwójne paski narzędziowe

 

Wyglądało to na swój sposób tragicznie. Istnieje niestety tylko jedna opcja, która pozwala przywrócić IDE to stanu poprzedniego. Wszystkie innej (tj. próba zresetowania ustawień w Tools->Import/Export Settings…, czy usunięcie katalogu VisualStudio z Moich Dokumentów) spełzły na niczym.

A oto przepis, który wszystko przywraca do normalności:

devenv.exe /ResetUserData



Z radością donoszę, że konkurs organizowany razem z Wrocławską Grupą .NET doszedł do skutku. Rozpoczyna się on już dziś (choć konkretniej to wczoraj) - 15 czerwca 2010! Trwał będzie aż do 21 września 2010!

W konkursie do wygrania cenne nagrody - 3 imienne komercyjne licencje na użytkowanie najnowszej wersji PostSharp 2.0, których fundatorem jest Paweł Hofman (CodeTitans.pl). Dalsze szczegóły dostępne są na stronie organizatorów tutaj. Życzę sukcesów i dobrej zabawy!

 

 PostSharp Wroc.NET



Stało się i znów jest problem. Jednego dnia zamykamy sprawny komputer, drugiego okazuje się, że zamiast włączać się jak zawsze (powiedzmy, że bez większych problemów) nasz Windows 7 ciągle się restartuje, uruchamia tryb odzyskiwania systemu lub testuje pamięć. Objawy o tyle dziwne, że wzięły się znikąd (tzw. efekt skraplania się z powietrza), a Windows wygląda, jakby chciał działać, a jednak nie mógł. Widać bowiem i animowane logo ‘okienek’ i pasek postępu, a nagle wyskakuje dialog odzyskiwania systemu i poszukiwania zaistniałego problemu.

Poczekawszy, aż proces odzyskiwania się zakończy (co u mnie niekiedy trwało i 10 minut), z logów dowiedziałem się, że wszystko jest OK, że przeprowadzono 1000 razy próbę ratunku i że mogę wysłać wieści do Redmont. Dopiero na samym końcu widniał napis w stylu:

Plik sterownika “C:\WINDOWS\system32\drivers\sptd.sys” jest uszkodzony.

Jakiekolwiek próby automatycznego odtworzenia tego pliku się nie udawały. Windows też nie próbował pominąć tego sterownika przy starcie i po prostu uruchamiać się dalej, tkwiąc w martwym punkcie po kolejnym restarcie. Wykonane testy pamięci nie zwróciły żadnego błędu. Wyjście awaryjne w postaci cofnięcia się do jednego z Punktów Odtwarzania Systemu, również się nie powiodło. Niby komunikat przed ich wykonaniem informował, że nie można przerwać tego procesu, ale gdzieś w środku wyskakiwał błąd z magiczną wartością 0x8xxx…

Na szczęście naciśnięcie F8 przy uruchamianiu komputera na płytach Asusa wyświetla menu z listą dysków twardych. Mogłem uruchomić dzięki temu inny z moich systemów operacyjnych i próbować szukać rozwiązania. W tym samym czasie skanowanie powierzchni partycji z systemem Windows 7 nie wykazało najmniejszego problemu. Sprzęt sprawny, komputer dzień wcześniej działał, to o co chodzi? Ano o to, że sterownik sptd.sys to: SCSI Pass Through Direct, czyli jeden z wielu sterowników dostępu do danych przestał działać! Jest on używany między innymi przez Daemon-Tools do świadczenia swoich usług i potwierdzania swojej ‘fizyczności’. No ale Daemony miałem zainstalowane od miesięcy i wszystko działało…ot złośliwość losu… Zmiana nazwy pliku ISO, który był włożony do wirtualnej stacji oczywiście też nie poprawiła sytuacji i system się nadal nie uruchamiał.

Rozwiązanie:

  1. Po zakończonej próbie automatycznego odzyskiwania, wybieramy ‘zaawansowane’ opcje (widoczne jako niebieski odnośnik na dole głównego okna programu).
  2. Wpisujemy login i hasło dla administratora komputera.
  3. Uruchamiamy terminal (potocznie znany tryb MS-DOS lub konsolą), w którym nawigujemy do katalogu system32/drivers i zmieniamy nazwę pliku sptd.sys, na jakąkolwiek inną (odsyłam do pomocy poleceń: cd, cp, del).
  4. Uruchamiamy komputer ponownie i tym razem uruchomi się bez najmniejszego problemu. Wszystko będzie działać prócz wirtualnej stacji DVD.
  5. Ze strony autorów sterownika SPTD (www.duplexsecure.com) pobieramy najnowszą wersję, którą dzisiaj jest v1.69 i instalujemy.
  6. Koniec. Wszystko wraca do normy.


Na szczęście autorzy Subversion przewidzieli, że potrzeba czasem przenieść repozytorium z jednej lokalizacji do drugiej z zachowaniem pełnej historii.

Pobieramy i zapisyjemy w pliku 'repo.dump' istniejące rewizje poleceniem:

svnadmin dump <ścieżka_do_źródłowego_repozytorium> > repo.dump

Na ekranie zobaczymy postęp w formie:

* Dumped revision 0.
* Dumped revision 1.
* Dumped revision 2.
* Dumped revision 3.
* Dumped revision 4.
* Dumped revision 5.
* Dumped revision 6.
* Dumped revision 7.
......

 

Odtwarzamy dane w nowym repozytorium poleceniem:

svnadmin load <ścieżka_do_nowego_repozytorium> < repo.dump

Co się objawi poprzez serie komunikatów o zaaplikowanych zmianach dla konkretnej wersji i może trwać dość długo (jeśli weźmiemy pod uwagę fakt, że robimy to na dość wolnym urządzeniu, które skonfigurowaliśmy uprzednio tutaj).

     * adding path :  ... done.
     * adding path :  ... done. 
     * adding path :  ... done                                                             .

------- Committed revision 18 >>>



Na początku serii porad o zarządzaniu i operacjach z serwerem SVN pokażę najprostszą rzecz – a mianowicie utworzenie nowego repozytorium. Zakładam jednocześnie, że będzie ono hostowane na naszym lokalnym routerze z systemem OpenWRT BackFire 10.03 oraz, że w chcemy mieć do niego dostęp przy użyciu protokołów svn:// i svn+ssh://, zależnie od tego, z której strony się łączymy.

Prawdopodobnie Subversion nie jest jeszcze zainstalowany w ogóle. Dlatego, aby się upewnić sprawdzamy listę zainstalowanych dodatków:

opkg update
opkg list-installed | grep subversion

Jeśli w wyniku zobaczymy na ekranie wpisy o SVN, to znak, że wszystko jest OK. W przeciwnym wypadku najlepiej pobrać już przygotowaną oficjalną dystrybucję ze strony openwrt.org i spróbować ją zainstalować. Służy do tego polecenie:

opkg update
opkg install subversion-server subversion-client

Następnie wracamy do meritum sprawy i tworzymy repozytorium poleceniem:

svnadmin create -fs-type fsfs /sciezka_do_repozytorium

Nowe repozytorium (z rewizją 0.) momentalnie zostanie stworzone. Dalej, edytujemy pliki konfiguracyjne, aby umożliwić sobie zdalny dostęp oraz minimum bezpieczeństwa:

  • w katalogu /etc/config edytujemy plik subversion:

    config subversion
            option path     '/ścieżka_do_repozytorium'
            option port     '3690'
  • w katalogu /ścieżka_do_repozytorium/conf edytujemy plik svnserve.conf:

    ustawiając brak możliwości logowania anonimowego, dając pełnię praw do zapisu zalogowanym poprawnie użytkownikom oraz wskazujemy plik, gdzie znajduje się lista użytkowników i ich haseł

    anon-access = none
    auth-access = write
    password-db = passwd
  • w końcu definiujemy użytkowników w pliku passwd (pozostając nadal w folderze conf naszego repozytorium). Cóż, plik ten nie jest w żaden sposób zabezpieczony. Także gdy już inny zły użytkownik znajdzie ten folder lokalnie, to nie będzie miał żadnego problemu z odzyskaniem i podmianą haseł, dlatego lepiej NIE używać tutaj hasła roota i podobnych.
  • na sam koniec uruchamiamy usługę subversion odpowiednim poleceniem tak, aby włączała się ona automatycznie po restarcie systemu (i gwarantowała dostęp po niezabezpieczonym protokole svn://):

    /etc/init.d/subversion start
    /etc/init.d/subversion enable


    (podpowiedź: po prostu startuje to proces svnserve na porcie 3690 oraz tworzy odpowiednie dowiązanie symboliczne S50subversion w katalogu /etc/rc.d, co powoduje, że będzie on włączany podczas ładowania systemu)

    W ramach testu możemy w tym miejscu posłużyć się TortoiseSVN i w Przeglądarce Repozytorium wypróbować adres: svn://openwrt/ (zamiast ‘openwrt’ należy wstawić nazwę nadaną naszemu routerowi lub po prostu jego adres IP z sieci wewnętrznej). Powinniśmy momentalnie zobaczyć monit o podanie nazwy użytkownika i hasła. Jeśli trwa to dłużej, to coś jest zepsute.
  • dodatkowo, w zależności od tego, z której strony routera chcemy się dostawać do repozytorium (od środka sieci lokalnej, czy z zewnątrz od WAN) tworzymy lub nie dziurę na porcie 3690 w firewallu. Sposób jak tego dokonać opisano tutaj. Pamiętajmy jednak, że przesyłane dane NIE będą w żaden sposób zabezpieczone ani zaszyfrowane. Jeśli zależy nam na bezpieczeństwie, to zalecane jest w tym momencie nie używanie tego połączenia z zewnątrz naszej sieci i czytanie dalej.

Gwarancję bezpiecznego dostępu do danych w naszym repozytorium zapewni nam tunelowanie. Tzn. w naszym przypadku skupimy się na przesyłaniu niezaszyfrowanych danych protokołem svn:// po szyfrowanym tunelu SSH. W ten sposób już nikt nie podsłucha tak łatwo wymiany danych z serwerem. Tutaj kroki, aby zaczęło to działać są nieco bardziej skomplikowane, bo najpierw:

  • zakładamy nowego użytkownika lokalnego, który będzie używany do logowania się na router. Mocno odradzam używania root’a w tym celu. Opis jak założyć użytkownika znajduje się tutaj. Pamiętajmy, aby użytkownik ten miał zdefiniowany poprawny katalog domowy oraz hasło! Hasło można nadać wykonując polecenie:

    passwd <nazwa_użytkownika>

    (uwaga: od tej pory, logując się do SVN przez SSH, plik z hasłami definiowany w katalogu conf repozytorium będzie ignorowany i SVN będzie zakładało, że poprawna autoryzacja SSH jest wystarczająca, a wszystkie zmiany będą odbywały się w kontekście właśnie tego użytkownika!)
  • otwieramy port 22 od strony połączenia WAN, co umożliwi nam zdalne logowanie SSH (jako dodatkowe zabezpieczenie możemy otworzyć inny port, który tylko my będziemy znać i robić przekierowanie na port 22 lub zmienić port nasłuchiwania usługi SSH)
  • jako test w tym momencie możemy wykonać na dowolnym innym komputerze podłączonym do naszej sieci:

    ssh <nazwa_użytkownika>@<IP routera od strony WAN>

    lub

    ssh –p <number_portu_jeśli_inny_niż_22> <nazwa_użytkownika>@<IP routera od strony WAN>

    lub wykorzystać program Putty, gdy testujemy z Windowsa.
  • tworzymy jeszcze tylko dowiązanie symboliczne na routerze, abyśmy nie musieli pamiętać ścieżki do repozytorium i mieli je zawsze dostępne pod hasłem “repo”

    ln –s /ścieżka_do_repozytorium /repo
  • na sam koniec przechodzimy do konfigurowania klienta, gdzie musimy zdefiniować odpowiedni ‘tunel’. Na moim komputerze wygląda to tak, że w katalogu “~/.subversion” należy edytować plik config i dodać tam w sekcji “[tunnels]” następującą linijkę (wszystko w jednej linii!):

    ssh = $SVN_SSH ssh –q –p <numer_port_od_strony_WAN_dla_SSH>
                          –l <nazwa_użytkownika_do_logowania_SSH>
  • Gotowe! Od tej pory pobieramy repozytorium poprzez nieco zmodyfikowany adres:

    svn co svn+ssh://<adres_publiczny_naszego_routera>/repo <lokalny_folder_gdzie_zapisać_pliki>

    Jeśli nie utworzyliśmy dowiązania ‘repo’ to w jego miejscu musimy wpisać całą ścieżkę lokalną do repozytorium, co nie musi być zawsze oczywiste.

    Jedyny mankament to to, iż za każdym razem, gdy mamy odwiedzić repozytorium musimy wielokrotnie wpisać hasło. Mi to nie przeszkadza, ale mimo wszystko to też da się obejść. Odsyłam do popularnego tematu w google ‘automatyczne logowanie SSH’.

Od tej pory wersjonowanie plików stało się jeszcze przyjemniejsze!



Jakiś czas temu awarii uległ mój router Asus WL-500gP. Sam moment zejścia trwał dość długo, bo około miesiąca i objawiał się dosyć dziwnie, w różnych etapach żywotności. Aż w końcu pewnego dnia, umarł, a później cudownie ożył! Ale po kolei.

Najpierw zastałem go resetującego się raz po raz. Było to o tyle ciekawe, iż na pierwszy rzut oka wpływ na to miało uruchamianie się WiFi. Zazwyczaj to po zapaleniu tej lampki następował restart. Dla tego routera dostępna jest cała gama nieoficjalnych firmwarów, więc pierwsze co w tym momencie przychodzi do głowy, to wgrać inny. W oryginalnym zapewne był błąd, który akurat mnie dopadł (po 2-ch latach użytkowania, ale zawsze). Spróbowałem openWRT i Oleg dla Asus WL-500gX. Router pochodził jeszcze tydzień i znów zaczął zachowywać się niestabilnie.

Tym razem objawy były dużo bardziej zaskakujące. Zaraz po podłączeniu do prądu zapalały się wszystkie lampki (all lights on) od tej z zasilaniem poprzez połączenia sieciowe (mimo, że kable nie były włożone) i WiFi. Dalej nie robiło się już nic. I tutaj się trochę poddałem, bo wszystko wskazywało na jakieś uszkodzenie sprzętowe. Po rozkręceniu obudowy, napięcia jakoś wyglądały, kondensatory się ładowały, zatem to musiała być pamięć FLASH, gdzie zapisany był bootloader lub sam firmware i nic nie jest uruchamiane, bo nic się nie da odczytać. Wszystko idzie w krzaki. W takim stanie router ten przeleżał dłuższy czas, aż w forum Asusa znalazłem potencjalną przyczynę mojego problemu – uszkodzony zasilacz!

Otóż oryginalny zasilacz (POWER SUPPLY UMEC UP0181B-05PE; +5V, 2.5A = 12.5W) ma tę własność, iż psuje się dobitnie tak, że daje podczas pracy zbyt niskie parametry prądu. To co jest najciekawsze to to, iż daje on w ogóle jakieś napięcie i natężenie, ale zbyt małe, aby pozwolić routerowi na poprawne uruchomienie. Wyjściem okazała się tutaj wymiana tego elementu, co kosztuje nieco ponad 20 PLN (wliczając dostawę do domu). Oprócz napięć, ważny jest typ końcówki, który w tym wypadku ma wymiary 2.1/5.5. Wiele innych modeli dLink oraz Linksys również używa tego zasilacza, dlatego jego zakup nie jest trudny.

Wszystko wróciło do porządku (i początku)!



VisualSVN oprócz wersji klienta SVN, od niedawna udostępnia również instalator, który pomaga w łatwy i przyjemny sposób udostępniać usługę SVN-serwer na własnych serwerach developerskich poprzez HTTP/HTTPS. Razem z binariami do zarządzania repozytorium, instalowany jest serwer Apache (lub to co jest z niego wymagane) oraz autorski panel administracyjny. Poprzez niego zakładane są repozytoria, przypisywane uprawnienia użytkowników oraz generowane (przypinane) certyfikaty SSL dla połączeń HTTPS.

To co ucieszyć może domorosłych programistów i administratorów to fakt, iż nawet darmowa wersja pozwala na wykorzystanie go w pracach nad komercyjnymi produktami. Dodatkowym atutem jest fakt, iż bardzo łatwo integruje się z domeną Active Diretory.



Zadanie na dzisiaj: instalacja programu MediaGo na komputerze z systemem Windows XP SP3 PL, a dokładniej – próba instalacji pomimo błędu:

Installing Microsoft Windows Imaging Component
One or more features could not be installed. The installation has been stopped.
Click Cancel to exit.


Installing Microsoft Windows Imaging Component

Okazuje się, że Sony Ericsson przy pisaniu tego instalatora dał plamę na całej linii. Niezależnie od tego, co byśmy robili, instalacja zakończy się błędem w najmniej oczekiwanym momencie – podczas aktualizacji komponentu Windows Imaging. Można go również bezpośrednio pobrać tutaj i spróbować aktualizować samodzielnie.

Przy własnoręcznej próbie instalacji tego komponentu dowiemy się w końcu, gdzie tkwi błąd. Otóż w systemie jest już zainstalowana nowsza wersja (dokładniej, to o jakieś dwa lata) i jej nadpisanie nie jest dopuszczalne. Aby obejść ten problem należy wykonać trzy proste kroki:

  1. założyć nowy folder i przenieść do niego następujące pliki z katalogu C:\Windows\System32:

    windowscodecs.dll
    windowscodecsext.dll
    photometadatahandler.dll
    WMPhoto.dll
  2. ponownie uruchamiamy instalator MediaGo (tym razem wszystko się powiedzie)


    Installing MediaGo
  3. przywracamy przeniesione pliki w kroku (1) na ich właściwe miejsce w C:\Windows\System32, nadpisując te, które wgrał tam instalator.

Odtąd możemy cieszyć się naszą aplikacją i kopiować zdjęcia oraz wideo na telefon.



Najlepiej jest być na bakier z wszelkimi zasadami zdroworozsądkowymi. Dlatego też postaram się w skrócie opisać, w jaki sposób zwykłemu szarakowi (czytaj: użytkownikowi bez jakichkolwiek uprawnień w domenie) pozwolić logować się na głównym kontrolerze domeny z zainstalowanym Windows Server 2008. Większość administratorów uderzyła już w tym momencie głową w biurko, zastanawiając się nad celowością takiego postępowania… toteż nikt nie będzie przeszkadzał.

Do dzieła, a zatem:

  1. Na kontrolerze domeny w narzędziu Server Manger znajdujemy gałąź Default Domain Policy (najszybciej po ścieżce: Features\Group Policy Manager\Fores: <domena>\Domains\<domena>\Default Domain Policy)
  2. Otwieramy Group Policy Management Editor poprzez wybranie Edit z menu kontekstowego.
  3. Dalej, nawigujemy do tej części, która pozwala nadawać i odbierać uprawnienia użytkownikom: Computer Configuration\Windows Settings\Security Settings\Local Policies\User Rights Assignment.
  4. Na koniec zezwalamy użytkownikowi na logowanie w trybie Terminal Services (KB278433), poprzez dodanie tam całej grupy Remote Desktop Users.
  5. Aby jeszcze wszystko szybko weszło w życie, wymuszamy odświeżenie polis w domenie: gpupdate /force.
  6. I to wszystko. Użytkownik nie musi mieć nawet uprawnień logowania lokalnego.

Dodatkowo uwaga:
- firewall musi mieć dziurę na przychodzące połączenia od usługi “Remote Desktop
- sama usługa natomiast musi być włączona :)
- użytkownik, któremu pozwalamy na logowanie musi należeć do grupy “Remote Dektop Users”, ale to już chyba zbyt oczywiste.