Menu

Pomiędzy bitami

Techno, porno i duszno. Blog niezupełnie technologiczny.

DSP2017

Raspbian i uruchomienie modemu GSM Huawei E3131

rozieblox

Uruchomienie modemu Huawei E3131 (hilink) pod Debianem opisałem wcześniej, ostatnio pisałem o perypetiach związanych z tym, że na Debianie działa, na Raspbianie nie działa. Dziś zagadka została rozwiązana.

Udałem się na kanał IRC Raspbiana, w nadziei, że dostanę wskazówki w czasie kiedy będę przeprowadzać debug. Czasami nie ma się co męczyć, bo po prostu można o czymś nie wiedzieć, jak miało to miejsce w przypadku uruchomienia SSH na Raspbianie. Poza tym, takie pytanie o pomoc i dostarczenie pełnych danych o problemie działa trochę jak gumowa kaczuszka.

Nim dobrze skończyłem pisać, dostałem namiar na ten wpis. Wygląda paskudnie? Ano wygląda. Ale działa - po wydaniu podanego polecenia pojawił się interfejs eth1 w systemie. Ale być może wystarczy doinstalować sg3-utils? Niestety nie - opisany sposób działa tylko do rebootu Raspberry Pi czy też do wyjęcia i włożenia modemu (nie pamiętam, oba mało akceptowalne...). Od biedy mógłbym z tym żyć, bo prosty skrypt do crona załatwi sprawę, ale... na Debianie jest bardziej elegancko, więc drążyłem temat.

Skoro przyszło do pakietów, to zauważyłem, że na desktopie mam zainstalowany pakiet:

ii  modemmanager                              1.6.4-1                                                 amd64        D-Bus service for managing modems

Brzmi obiecująco, tym bardziej, że dotyka D-Bus. Na Raspbianie tego pakietu nie było... Doinstalowałem pakiet, reboot Raspberry Pi i... Działa. Nie jest identycznie jak w Debianie, bo nadal interfejs to eth1 i IP pobiera automatycznie z DHCP, ale to detale - najważniejsze jest działające wyjście na świat.

Podsumowując: aby działały modemy typu dongle USB w Raspbian, należy doinstalować pakiet modemmanager.

Wpis pojawia się w kategorii DSP2017 z racji tego, że płytka z ARM będzie robiła za stację testową. Jeśli wszystko pójdzie dobrze, jeszcze dziś...

Prawie jak stacja testowa

rozieblox

Były święta i wolne. W planach miałem uruchomienie stacji testowej w domu, na Raspberry Pi, ale po namyśle stwierdziłem, że jednak wolę zamienić Banana Pi, robiące aktualnie za router u rodziców z moim Raspberry Pi i testować na BPi. Przy okazji miałem nadzieję wyjaśnić zagadkę niedziałającego z BPi zasilacza domowej produkcji, który świetnie działa z RPi. Podejrzewam kabel USB, ale o tym innym razem.

W każdym razie spakowałem RPi z zainstalowanym podstawowym systemem i dostępem po SSH, wziąłem też sporo kabli USB, zasilacze, mirniki napięcia. Ot, wszystkie okoliczne graty. Wziąłem też testowy modem Huawei E3131, na wypadek gdyby przyszło mi do głowy zastąpienie istniejącego, również Huawei E3131 tyle, że starszej generacji, bez hilink.

Na miejscu dokonałem szybkiego kopiowania skryptów i... przyszedł mi do głowy szatański plan. Przecież mogę uruchomić oba modemy w RPi i testować w warunkach produkcyjnych. Tyle, że zdalnie. Niestety, szybko okazało się, że mimo starannego choć szybkiego skopiowania skryptów RPI nie nawiązuje łączności ze światem. Wielkiej filozofii w skryptach nie ma, prawa identyczne. Stary Huawei nie chce działać. Wetknąłem więc nowy modem, z hilink i stwierdziłem, że w sumie najwyżej zostanie RPi z nowym modemem robiące za router, a BPi przetestuję po powrocie do domu i od razu zrobię z niego stację roboczą. Tyle, że okazało się, że modem z hilink niby nawiązuje połączenie (jest ustawiony, by robił to automagicznie), przynajmniej wskazuje na to kolor diody ale... w systemie nie powstaje interfejs. Czyli żaden z dwóch modemów na USB nie zadziałał na RPi!

Lekko tylko klnąc pod nosem szybko wróciłem do działającej konfiguracji z Banana Pi robiącym za router GSM, czyli zupełnie do punktu wyjścia, bez jakichkolwiek postępów - ani nie mam uruchomionej stacji testowej, ani nie zluzowałem BPi w celu przetestowania zasilacza.

Jednak są pewne... zmiany, bo ciężko to nazwać postępem:

  • Mam zagadkę pt. "na Raspbianie nie działają modemy USB". Jak patrzę we wcześniejszy wpis o SSH, to jakiś Raspbian Lite. Może to jest przyczyną? Może customowy kernel Raspbiana? Przetestuję w chwili wolnej.
  • Jakimś cudem zadziałało zapięcie Banana Pi zarówno jako źródła danych, jak i "klienta" w hubie USB. Jak ostatnio sprawdzałem, to w tej konfiguracji się nie uruchamiał, a RPi działało bez problemu. Zastanawiam się, czy znowu nie chodzi o kabel.
  • Kolejnym zaskoczeniem jest to, że Raspberry Pi nie musi być wpięte w ww. sposób do huba USB, by działało. Okazało się, że wystarczy je zapiąć jako źródło danych i... dostaje zasilanie. Jest to dla mnie totalną zagadką, bo do tej pory nie przyszło mi do głowy, ale działa. W sumie fajne, bo mam jeden port w hubie USB więcej wolny.


Czyli w DSP2017 zastój, ale czegoś nowego się dowiedziałem i jest co robić. Następny wpis raczej również będzie metatematyczny, prawdopodobnie znowu o ciekawych projektach w DSP2017. Z rzeczy związanych bardziej bezpośrednio - prawdopodobnie w przyszłym tygodniu jakąś stację testową jednak uruchomię. Mam nadzieję, że będzie to RPi z rozwiązaną zagadką modemów USB...

Status abcc - 75% zrobione

rozieblox

Za wiele się nie wydarzyło w tym tygodniu w projekcie. Nie uruchomiłem i raczej nie uruchomię stacji testowej, bo jakoś nie ma weny. Za to zrobiłem względny porządek z opisami i funkcjonalnościami, więc powinno dać się względnie komfortowo uruchomić. Gdyby ktoś miał Linuksa i chciał się pobawić - zapraszam i czekam na uwagi. Póki co wyniki są wyświetlane na stdout i całość nie działa w pętli, tylko wykonuje jeden przebieg, ale to detale.

Rozważam uruchomienie stacji testowej oraz przejście na wypisywanie rzeczy do dorobienia/poprawki jako issues.

Czas na DSP2017 został zjedzony przez inną nową zabawkę - Pyevolve. Jest to biblioteka do algorytmów genetycznych, które chcę wykorzystać do rozwiązywania pewnego zagadnienia. No i wsiąkłem w testy, zabawę, przeglądanie dokumentacji i kodu. Z zalet: chyba pierwsza biblioteka, która wygląda na używalną. Jeśli ktoś zna inne godne uwagi (proste, rozszerzalne), to poproszę namiar.

A skoro o algorytmach genetycznych mowa - jest konkurs dotyczący algorytmów genetycznych. Chociaż ja się na grant raczej nie łapię...

Allegro Tech Talks Poznań #4 - wrażenia

rozieblox

W projekcie abcc panuje chwilowy zastój, spowodowany czynnikami różnymi - od osobistych (bardziej, znacznie bardziej), przez zawodowe (mniej, znacznie mniej), ale faktem jest, że spocząłem na laurach nieco i nic się od ostatniego wpisu nie zmieniło w temacie. Plan jest taki, żeby uruchomić sobie stację testową opartą o Raspbbery Pi, która będzie działać na dwóch lub trzech łączach (kabel, modem GSM i być może, jeśli RPi wyrobi prądowo, karta WiFi) i zrzucać pomiary, w celu lepszego dobrania parametrów. Ale to plany...

Tymczasem w ramach pożeraczy czasu byłem w zeszłym tygodniu na spotkaniu Allegro Tech Talks Poznań #4. Staram się bywać, jeśli akurat mam czas. Jeśli dobrze zrozumiałem, po raz pierwszy można było wysłuchać przez net na żywo, ale jakoś nie przepadam za taką formą - lepiej mi się obiera na żywo, nie mam nawyku słuchania przez net. No i zawsze można spotkać znajomych i poplotkować.

Prezentacje były dwie, obie dotyczyły Apache Solr, więc zupełnie nie moja działka, i przyznaję, że wahłem się, czy w ogóle iść, ale obie były IMO bardzo dobrze i interesująco poprowadzone, więc części merytorycznej też nie żałuję.

Pierwsza prezentacja dotyczyła uruchamiania Solra w kontenerach dockerowych, poczynając od tego jak to skonfigurować i uruchomić, przez przedstawienie wyników benchmarków pomiędzy sprzętem fizycznym (bare metal), przez pełną wirtualizację, po kontenery. Różnice były duże, przedstawione dane przekonują do kontenerów, ale... Zawsze jest jakieś ale, w tym przypadku testy były robione na ustawieniach domyślnych. Z jednej strony rozumiem, bo jakiś wspólny mianownik trzeba mieć, z drugiej produkcję konfiguruje się pod konkretny przypadek. Niemniej, różnice były na tyle istotne, że konfiguracja raczej nie będzie w stanie ich zniwelować. W sumie można było traktować tę prezentację mniej jako o Solr, bardziej jako o dockerze.

Druga prezentacja dotyczyła optymalizacji Solra w Allegro. Jak pisałem, nie moja działka, więc momentami była to trochę chińszczyzna (na zasadzie: nie wiem co to dokładnie jest), ale opowiedziane przystępnie, ciekawie i z przykładami. Mocno nieoczywiste przypadki i wyniki, efekty dobre. Stawiam, że dla osób zajmujących się Solrem perełka. Jest dostępna w wersji online.

Spotkałem też starych znajomych i poplotkowaliśmy, więc ogólnie bardzo udane wydarzenie - 10/10.

Pierwsze pomiary

rozieblox

Wygląda, że w końcu mogę napisać, że powstało coś działającego. Nie jest to oczywiście pełna funkcjonalność, ale same pomiary są skończone. Nie twierdzę, że to ostateczna wersja, w szczególności muszę się przyjrzeć logowaniu, ale to jest ten moment, kiedy mogę pobawić się wartościami z konfiguracji i zobaczyć, jak wpływają na działanie w realnych warunkach.

Jak to wygląda? Otóż tak na szybko, uruchamiając modem GSM w sieci Virgin Mobile (3G) zarejestrowany do T-Mobile (roaming):

INFO:__main__:Route default got score 24.1516556059 on interface wlan0
INFO:__main__:Route default got score 89.6018913814 on interface enx582c80xxxxxx
INFO:__main__:Route default got score 23.7111227853 on interface wlan0
INFO:__main__:Route default got score 64.5852940423 on interface enx582c80xxxxxx
INFO:__main__:Route default got score 24.101962362 on interface wlan0
INFO:__main__:Route default got score 63.8392652784 on interface enx582c80xxxxxx
INFO:__main__:Route default got score 23.9711829594 on interface wlan0
INFO:__main__:Route default got score 78.0421457793 on interface enx582c80xxxxxx
INFO:__main__:Route default got score 66.7648989057 on interface wlan0
INFO:__main__:Route default got score 62.6970052719 on interface enx582c80xxxxxx

Widać, że w ostatnim pomiarze domowe WiFi (lub operator, ale stawiam na WiFi) dało się we znaki i wypadło gorzej, niż modem GSM. Różnica jest jednak minimalna i do zmiany routingu by nie doszło, nawet na domyślnych wartościach.

Wyniki po zalogowaniu natywnie, czyli do Play:

INFO:__main__:Route default got score 23.7996305738 on interface wlan0
INFO:__main__:Route default got score 307.032244546 on interface enx582c80xxxxxx
INFO:__main__:Route default got score 24.561555045 on interface wlan0
INFO:__main__:Route default got score 267.205837795 on interface enx582c80xxxxxx
INFO:__main__:Route default got score 24.0223884583 on interface wlan0
INFO:__main__:Route default got score 268.849682808 on interface enx582c80xxxxxx
INFO:__main__:Route default got score 23.7405095782 on interface wlan0
INFO:__main__:Route default got score 275.927570888 on interface enx582c80xxxxxx
INFO:__main__:Route default got score 38.6582265223 on interface wlan0
INFO:__main__:Route default got score 287.999381338 on interface enx582c80xxxxxx

Wszystkie wyniki dla przykładowego pliku konfiguracyjnego z repo, z dostosowaną nazwą interfejsu (jest interfejs modemu zamiast eth0) i zmienionym poziomem logowania na INFO. Wywołanie w pętli 5 razy:

for i in {1..5}; do python abcc.py --config local_test.yaml; done

Przyznaję, że jestem zaskoczony wynikami - wydawać by się mogło, że natywnie będzie działać lepiej, a tu niespodzianka. Muszę jeszcze dokładniej potestować na różnych urządzeniach, dotychczas miałem wrażenie, że w roamingu jest gorzej. Ale to już temat na inny, niezwiązany z DSP2017, wpis.

Przy okazji, to drugie wywołanie wykonuje się 71 sekund, czyli około 14 sekund na jeden pełen przebieg, a ilość przesłanych podczas badania danych (odczyt z ifconfig) to:

RX packets 11342  bytes 7440400 (7.0 MiB)
TX packets 9789  bytes 1133957 (1.0 MiB)
RX packets 11640  bytes 7475184 (7.1 MiB)
TX packets 10087  bytes 1169257 (1.1 MiB)

Czyli jakieś 7kB RX i 7 kB TX per pomiar. Czyli jakieś 10 MB/dobę, przy założeniu, że będzie wywoływane co minutę, 27/7. Czyli mniej więcej mieści się w limicie bezpłatnego pakietu Freemium w Virgin Mobile. :-)

Skrypty pomocnicze

rozieblox

Wspominałem, że pewna część działania skryptu odbędzie się w zewnętrznych skryptach. Powiedzmy, że pluginach, choć to myląca nazwa. I że będą w Bashu.

Zrobiłem listę skryptów pomocniczych, których planuję używać:

  • ustawianie routingu do danego IP przez dany interfejs (bardziej gateway)
  • usunięcie routingu do danego IP przez dany interfejs (gateway)
  • ustawienie (domyślnego) routingu przez dany interfejs i gateway
  • zdjęcie (domyślnego) routingu przez dany interfejs i gateway

Jeśli chodzi o postępy, to pojawiło się wsparcie dla interfejsów, zarówno po stronie skryptu, jak i konfiguracji. Tak naprawdę pojawiła się cała sekcja interfaces, dla każdego interfejsu są określone nazwy tras, których parametry są zdefiniowane w sekcji routes. Taka konstrukcja, bo przecież nie każdy interfejs musi umożliwiać routing do każdej sieci, a nie chcę wymuszać cokolwiek długiej definicji trasy dla każdego interfejsu. Poza tym, łatwo byłoby w takim przypadku o błąd typu inne wagi czy IP.

Żeby można było mierzyć jakoś łącza do danej sieci (route) przez dany interfejs brakuje tak naprawdę pierwszych dwóch skryptów i ich wywołania - stosowne funkcje istnieją, ale są puste. Pewnie jutro/pojutrze. Mam nadzieję, że od razu pokażę pierwsze realne efekty działania, czyli wyniki pierwszych pomiarów. Stay tuned!

DSP2017 - co ciekawsze projekty

rozieblox

Ostatni dzwonek na wpis, a w związku z aurą i nawałem innych zajęć niewiele się u mnie wydarzyło[1], więc pozwolę sobie zacząć małą metatematykę, czyli pisać o projektach, które przykuły moją uwagę i które planuję śledzić. Ocena zupełnie subiektywna. Raczej ograniczam się do "żywych", czyli mających szanse w konkursie, projektów. Trochę nawiązując do Blog Day, ograniczę się jednorazowo do pięciu sztuk. Docelowo pewnie zmienię linki na bezpośrednie do blogów lub repo na GitHubie.

http://uczestnicy.dajsiepoznac.pl/profil/adrian-dzik - Instant Dinner czyli podpowiadanie co tu ugotować z dostępnych w lodówce składników. Pomysł mi się bardzo podoba i może się przyjąć, choć korzystać raczej nie będę - nie mam cierpliwości do wklepywania wszystkiego i nie lubię gotować z przepisów. Parę ciekawych wyzwań - interfejs, baza przepisów.

http://uczestnicy.dajsiepoznac.pl/profil/pawel-filipek http://uczestnicy.dajsiepoznac.pl/profil/pawel-panek - dwa projekty związane z modnym temat badania czystości powietrza. Tu: informowania o zanieczyszczeniu w danym miejscu. Po cichu liczę, że będzie kolaboracja z projektem Smolgy o którym niedawno pisałem.

http://uczestnicy.dajsiepoznac.pl/profil/kamil-kubacki - projekt Citizen, czyli zgłaszanie do władz miasta/służb uszkodzeń itp. Po prostu zgłaszasz dziurę w jezdni (geolokalizacja, fota, opis) i jest to odpowiednio przeroutowane dalej, nie trzeba się edukować/odbijać od kolejnych instytucji. Przyznaję, że myślałem o czymś podobnym niedawno. Widzę fajne możliwości - ranking najsprawniej działających miast/organizacji w danym mieście (np. czas od zgłoszenia do usterki). Widzę też jeden problem: żeby to działało, instytucje muszą się zaangażować...
Podobna tematyka http://uczestnicy.dajsiepoznac.pl/profil/andrzej-chmielewski - niestety wygląda na martwe.

http://uczestnicy.dajsiepoznac.pl/profil/maciej-sykala - działko na gołębie oparte o Raspberry Pi. Temat niezbyt mi się podoba, ale przyznaję, że zakres robi wrażenie i... ciekaw jestem efektu. BTW dawno temu czytałem, że w Korei Południowej studenci projektowali automatyczne wieżyczki strzelnicze do pilnowania granic. Nie pamiętam, czy była analiza obrazu, czy po prostu wykrywanie ruchu...

http://uczestnicy.dajsiepoznac.pl/profil/sebastian-czarnecki - arduino sterowane po wifi. To mi się najprawdopodobniej zwyczajnie przyda w niedalekiej przyszłości.

Na wypadek gdyby powyższe nie wyczerpywało wymagań wpisu o IT, to przyszła mi do głowy nieco inna formuła konkursu programistycznego, która mogłaby trochę pomóc w rozwoju projektów. Pierwszy etap to prezentacja pomysłów, pisanie kodu i blogowanie (czyli dokładnie jak DSP), drugi etap to połączenie się ludzi w zespoły i wspólne rozwijanie projektów. Można by to zakończyć jakimś hackatonem, żeby ludzie się poznali na żywo. A może istnieje już coś takiego?

Co prawda nie widzę za bardzo kryteriów oceny w powyższym układzie, ale mogłoby to dać coś trwalszego i większego, niż małe projekciki, nauczyć pracy w zespołach, umożliwić poznanie ludzi i wymianę wiedzy np. o narzędziach. No ale ja cały ten konkurs traktuję bardziej jako pretekst, czyli droga jest ważniejsza od celu. ;-)

[1] Przynajmniej niewiele zostało commitnięte, za to wkrótce pierwsze pomiary na dwóch łączach i pewne uwagi nt. internetu w Virgin Mobile.

Logowanie

rozieblox

Pora dorobić logowanie w skrypcie. Nie będę tu przepisywał tutoriali, więc jedynie odeślę do opisu logowania w Hitchhiker's guide to Python oraz chyba nawet lepszego wpisu na temat dobrych praktyk logowania w Pythonie Docelowo konfiguracja logowania w pliku konfiguracyjnym. Waham się czy jednak syslog, czy może osobny plik, ale to jest detal.

Wczoraj w pociągu rozpisałem wstępnie, co chciałbym logować na poszczególnych poziomach i wyszło mi coś takiego:

WARNING/ERROR:

  • błąd otwarcia lub parsowania pliku konfiguracyjnego
  • nieistnienie interfejsu zdefiniowanego w pliku konfiguracyjnym
  • błąd zwrócony przez skrypty pomocnicze
  • brak skryptu pomocniczego, jeśli był zdefiniowany w pliku konfiguracyjnym[1]
  • nieosiągalne IP[2]

INFO:

  • znalezienie lepszej trasy i zmiana routingu, czyli podstawa
  • ostateczna punktacja dla danego interfejsu (docelowo może w DEBUG?)
  • znalezienie lepszej trasy, niż istniejąca, z pominięciem kosztu przełączenia[3]

DEBUG:

  • chwilowe zmiany routingu per badane IP
  • dane wczytane z konfiguracji
  • parametry wywołania funkcji
  • punktacja dla interfejsu z rozbiciem na składowe
  • parametry wywołania skryptów pomocniczych

Domyślny loglevel to oczywiście INFO. Jeśli wszystko pójdzie OK,to zmiany pojawią się w repo dziś wieczorem - niestety czas goni, a dwa wpisy w tygodniu muszą być...

[1] Wybiegam w sekcję ogólną konfiguracji, która dopiero powstanie, o skryptach pomocniczych planuję napisać w kolejnym wpisie.
[2] Jeśli będzie często występowało, to warto je usunąć, żeby nie zaburzało wyników.
[3] W celu poinformowania użytkownika, że być może warto zmienić przy okazji konfigurację sieci.



Początek

rozieblox

No to wysłałem na GitHuba to co mam w tej chwili. Nie ma tego wiele - w zasadzie jeśli chodzi o kod to jest to dokładnie wersja testowa o której pisałem wcześniej. Zupełnie nie miałem czasu i weny na siedzenie z kodem.

Ale nie jest tak, że nic nie przybyło w kwestii projektu. Po pierwsze, dotarł modem i udało mi się go uruchomić, więc będzie na czym testować. Po drugie, zrobiłem lekkie porządki w plikach i zaktualizowałem opis. Po trzecie i najważniejsze: chyba rozwiązałem problem wag. Proste rozwiązania są najlepsze, na papierze i szybkim teście wygląda wstępnie OK. Oczywiście jest to średnia ważona - musiałem mieć jakieś zaćmienie, że od razu o niej nie pomyślałem, ale powiedzmy, że bardziej myślałem o pliku konfiguracyjnym.

Co poza tym w temacie DSP2017? U mnie nic, poczytałem za to trochę wpisów. innych uczestników Co prawda w repozytoria nie zaglądałem, ale z wpisów mogę wywnioskować, że wszyscy mają mało czasu, generują niewiele kodu za to piszą, bo... muszą. Czyli za dużo blogowania, za mało programowania, ale chyba autor konkursu świadomie tak wybrał. Wnioskuję po dopuszczeniu wpisu niezwiązanego tematycznie z projektem jako drugiego. IMVHO trochę szkoda, bo czas zabiera, a wnosi niewiele.

Wskaźniki jakości łącza

rozieblox

Dumałem trochę nad parametrami łącza internetowego, które abcc mógłby mierzyć, poza tym, komentarze pod wpisem o założeniach abcc trochę pomieszały mi szyki, jeśli chodzi o chronologię, więc najwyższy czas przejść do rzeczy.

Techniczne wskaźniki jakości łącza internetowego to:

  • Opóźnienie - czyli potocznie lag albo ping, zrozumiała chyba dla każdego miara i dość powszechnie używana do określenia, czy łącze jest sprawne. Im jest mniejsze, tym lepiej. Ma znaczenie przy korzystaniu interaktywnym, czyli SSH/remote desktop albo graniu w gry online (zwł. FPP). Niezbyt istotne przy pobieraniu danych czy strumieniowaniu.
  • Straty pakietów - na sprawnym łączu strat nie ma. W przypadku łącz bezprzewodowych lub awarii, straty mogą się pojawiać. Wiążą się z koniecznością retransmisji pakietów lub utratą danych. Mają znaczenie praktycznie wszędzie. Im niższa wartość, tym lepiej.
  • Jitter - zmienność opóźnienia pakietów, czyli dokładniej statystycznie, wariancja opóźnienia pakietów. Ma znaczenie przy korzystaniu interaktywnym, szczególnie przy transmisji głosowej/video. Im niższa wartość, tym lepiej.
  • Prędkość pobierania - określa, jak szybko można pobierać dane. Ważne przy pobieraniu danych.
  • Prędkość wysyłania - określa, jak szybko można wysyłać dane. Ważne tylko przy wysyłaniu większych maili itp.

W wariancie minimum planuję mierzyć tylko dwie pierwsze miary. Waham się nad jitterem - prawdopodobnie kiedyś zaimplementuję, ale wymagałoby zmiany bibliotek i/lub liczenia wszystkiego samodzielnie. Wykonalne, ale na początek mało istotne. Z uwagi na pierwotne zastosowania (GSM) i możliwość opłat za transfer, rezygnuję z badania prędkości pobierania i wysyłania. Zresztą, jest szansa, że same pomiary mogłyby tu wpłynąć na funkcjonowanie łącza, szczególnie słabszego. Dodatkowo wymagany jest host zdalny, udostępniający określoną zawartość (w przypadku downloadu) lub pozwalający na wysyłanie treści (w przypadku uploadu). Nie skreślam zupełnie, ale zdecydowanie nie pojawi się w pierwszej wersji, a jeśli się pojawi, to domyślnie będzie wyłączony.

Na koniec pozostała część zasadnicza, czyli formuła określająca jakość łącza. Ponieważ dla większości parametrów im niższa wartość, tym lepiej, stwierdziłem, że najprościej jest liczyć tylko koszt, czyli sumować "punkty karne", łącze o najniższej wartości "wygrywa". W przypadku dwóch ostatnich parametrów łatwo zamienić je na analogiczne miary - im niższy czas przesyłania znanej ilości danych, tym lepiej.

Ostatecznie na razie wyszło coś takiego:

f(route)= suma(mnożnik_IP * (mnożnik_strat_route * straty_IP + mnożnik_opóźnień_route * opóźnienie_IP))

Dodatkowo całość należałoby przemnożyć przez mnożnik dla danego łącza[1] i wprowadzić, czy to do wzoru, czy przy podejmowaniu decyzji o przełączeniu, koszt przełączenia. Docelowo przydała by się pewnie jeszcze jakaś normalizacja względem ilości IP, żeby dodanie dodatkowych IP do sprawdzania nie powodowało zmiany wartości, bo to zmienia rolę kosztu przełączania. Najprostsza byłaby średnia, ale gryzie się z mnożnikami dla poszczególnych IP. Te z kolei chciałem mieć, bo wyobrażam sobie sytuację, że ktoś chce sprawdzać jakość łącza do różnych IP docelowych, ale niektóre (np. IP firmy) są bardziej istotne przy podejmowaniu decyzji.

Mnożniki dla route wprowadziłem z uwagi na możliwość ustawiania nie tylko routingu domyślnego, ale dla poszczególnych tras. Może się zdarzyć, że do sieci, do której łączymy się przez SSH ruch będzie wysyłany innym łączem, niż podstawowe, ze względu np. na mniejsze opóźnienia. Raczej na wyrost w tej chwili, ale kiedyś pewnie się przyda.

Przechodząc do spraw praktycznych: pobawiłem się chwilę w weekend, jest PoC - czytanie konfiga, część przykładowego konfiga, przepingowanie IP, liczenie kosztu (niedoskonałe). Czekam na zamówiony modem GSM. 56 linii kodu, commit do repo pewnie w tym tygodniu, ale o tym następnym razem. ;-)

[1] Koszt łącza miałby być dodatkowym parametrem, dzięki któremu użytkownik może w jakiś sposób odwzorować parametry pozatechniczne, choćby koszt transmisji za pośrednictwem danego łącza.

Międzyczas

rozieblox

Zacząłem od opisu założeń i tym podobnych rzeczy nie związanych bezpośrednio z programowaniem, ale ciągnie wilka do lasu i chciałem się w międzyczasie na boku pobawić fragmentami kodu i modułami. Ponieważ już w komentarzach w poprzednim wpisie pojawiły się wzmianki o tym co będzie, nie będzie wielkiej szkody czy niespodzianki, jeśli nieco wybiegnę naprzód.

Na pierwszy ogień poszło pingowanie, bo właśnie w ten sposób chcę mierzyć jakość łącza. Jak można się spodziewać, do korzystania z ICMP wymagane są uprawnienia użytkownika root. Nie jest to dla mnie niespodzianką, bo spotkałem się z tym przy perlowym skrypcie do powiadamiania o konieczności wpisania CAPTCHA dla Aero2. Tym razem postanowiłem nie odpuścić, tym bardziej że w sumie dopuszczam - przynajmniej w pierwszej wersji - uruchamianie skryptu z użytkownika root. W końcu i tak będzie trzeba dotykać routingu, a do tego potrzebne są wyższe uprawnienia niż posiadają zwykli użytkownicy.

Żeby poznać najlepszy i zalecany sposób pingowania, wrzuciłem zapytanie do wyszukiwarki i... włos mi się zjeżył na głowie. Rozwiązań jest wiele, modułów jest wiele, a prostego i działającego jakoś nie widać. Zacząłem od prostego modułu ping, który ma funkcję quiet_ping robiącą to, co potrzebuję, ale o ile dał się bez problemu zainstalować z Python 2, o tyle z Python 3 ma problem:

virtualenv --python=python3 test
Already using interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /tmp/abcc3/test/bin/python3
Also creating executable in /tmp/abcc3/test/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.
source test/bin/activate
pip3 install ping
Collecting ping
  Using cached ping-0.2.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "", line 1, in
      File "/tmp/pip-build-qqotvnqc/ping/setup.py", line 23, in
        from ping import __version__
      File "/tmp/pip-build-qqotvnqc/ping/ping.py", line 196
        except socket.error, (errno, msg):
                           ^
    SyntaxError: invalid syntax
   
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-qqotvnqc/ping/

Z kolei próba użycia modułu python3-ping wygląda tak:

pip3 install python3-ping
Collecting python3-ping
  Could not find a version that satisfies the requirement python3-ping (from versions: 2014.05.01.022aa83, 2014.05.02.805ee25, 2014.05.02.16245f0)
No matching distribution found for python3-ping

Wgląda więc, że prawdopodobnie w pierwszym etapie, by nie tracić czasu, pozostanę przy Python 2, zachowując zgodność z Python 3, a najwyżej później dostosuję całość. Nie powinno być to trudne - wystarczy wymienić moduł i jego wywołanie, funkcje u mnie i argumenty raczej się nie zmienią. Będę wdzięczny za sugestię działającego modułu do pingowania. Oczywiście zawsze zostaje użycie systemowego polecenia ping i parsowanie wyjścia, ale tego wolałbym uniknąć...

Z innych newsów okołoprojektowych: zakupiłem modem GSM, żeby mieć na czym testować. Jest wbudowana karta w lapka, mam jakieś wifi na USB, dorzucę modem i wygląda, że nawet do pięciu łącz jestem w stanie w środowisku testowym mieć. Pewnie zostanę przy dwóch-trzech, ale dobrze jest mieć perspektywy. ;-)

Założenia i opis projektu abcc

rozieblox

Projekt abcc składa się z demona, napisanego w Pythonie, który czyta plik konfiguracyjny, a następnie na podstawie jego zawartości dokonuje cyklicznej kontroli jakości dostępnych łącz względem określonych w konfiguracji IP docelowych. Przeprowadzane operacje zapisywane są do logu (syslog?), podobnie jak oceny poszczególnych łącz.

Zakładam wykorzystanie Pythona w wersji 3, przestrzeganie PEP8 i programowanie funkcyjne. Całość ma być możliwie prosta koncepcyjnie i możliwie konfigurowalna przy pomocy pliku konfiguracyjnego za pomocą wag poszczególnych wskaźników, wag IP. Rozwiązanie ma też zapewniać użytkownikowi pełną przejrzystość działania, wybór poziomu logowania i możliwość uruchomienia w wersji "na sucho", w celu przetestowania, jak uruchomienie z daną konfiguracją wpłynęłoby na zmiany routingu.

Aby to osiągnąć, zmienia na czas pomiaru routing do docelowych IP na dane łącze, dokonuje pomiaru jakości łącza, a następnie, po zebraniu danych dla wszystkich łącz, określa, które z nich jest najlepsze i - jeśli zachodzi taka potrzeba, dokonuje zmiany routingu.

Do zmiany routingu wykorzystywane są zewnętrzne skrypty bashowe - pozwala to na dostosowanie działania demona do różnych platform i potrzeb - np. dodanie zmiany NATowanaia, wywołanie zmian na zdalnym systemie (router sprzętowy) - bez zmian w samym silniku.

Teoretycznie można by to napisać w czystym Bashu i wywoływać z crona, ale po pierwsze, chcę potrenować Pythona, po drugie tak będzie łatwiej, bardziej elegancko i będzie otwarta droga np. do zwiększenia częstotliwości próbkowania przez zrównoleglenie pomiarów.

Z racji wymogów konkursowych dotyczących ilości postów, tworzenie projektu będzie trochę przegadane, i spowolnione, przynajmniej na początku. Zaleta jest taka, że będzie lepiej widać sposób rozumowania, gdyby ktoś chciał coś skomentować lub się przyłączyć. Commity kodu i dokumentacji będą się pojawiały w miarę równolegle z wpisami na blogu, pierwszy właśnie poszedł.

Geneza, nazwa i zastosowania

rozieblox

Projekt, który mam zamiar zrealizować w ramach DSP2017 nazywa się abcc (Automatic Best Connection Chooser). Pierwotnie miał się nazywać abpppcc i działać dla połączeń PPP, ale w sumie nie ma to sensu. Pomysł narodził się, gdy kiedyś znajomy z FB napisał, że jest w drodze, ma 2 czy 3 połączenia GSM i przełącza się między nimi, bo raz lepiej działa to, raz tamto. Oczywiście przełącza się ręcznie.

Stwierdziłem, że gdyby miał Linuksa, to uruchomienie wszystkich naraz, sprawdzanie automatem i przełączanie ruchu na najlepsze nie powinno być trudne. Sprawę wstępnie przemyślałem, zacząłem nawet zabawę z dwoma modemami GSM, ale wkrótce pojawiły się ważniejsze sprawy i projekt trafił do szuflady. Znaczy na dysk. Nawet nie tyle projekt, co krótko spisane wstępne założenia i wymyślona nazwa.

Potem stwierdziłem, że rozwiązanie można zastosować też w innych okolicznościach, nie tylko przy laptopie w podróży. Może służyć do przełączania ruchu na łącze zapasowe w przypadku sieci i routera na Linuksie i pogorszeniu parametrów łącza podstawowego, a nawet... do sterowania ruchem operatorskim.

W tym ostatnim zastosowaniu oczywiste jest podobieństwo do rozwiązania firmy Border6 omówionego na PLNOG13, przy czym to co zamierzam napisać jest o wiele bardziej prymitywne, więc mam nadzieję, że klientów nie odbierze. Choć IMO ma szansę być opensource'ową namiastką.

Blox.pl - feed RSS dla pojedynczej kategorii

rozieblox

Wymaganiem udziału w konkuresie DSP2017 jest podanie feedu RSS zawierającego wyłącznie posty związane z konkursem. Blox.pl spłatał mi niemiłego figla i dał wybór - albo stary, paskudny wygląd, albo brak możliwości pobrania feedu RSS dla pojedynczej kategorii. Sprawę zgłosiłem, ale znając czasy realizacji stwierdziłem, że mam trzy możliwości: zrezygnować z DSP2017, postawić osobnego bloga specjalnie dla DSP2017 albo zrobić coś samemu.

Pierwsze dwie możliwości odrzuciłem. Jakoś nie widział mi się blog z 20 postami, kolejnego prowadzić mi się nie chce, a Blox ma swoje zalety i do porzucenia jeszcze nie dojrzałem. Spojrzałem co też mam do dyspozycji pod ręką, bo w pewne parsowanie feedu RSS bawiłem się już przy pomocy Perla (patrz zawartość mojego konta na blabler.pl). Niestety, stwierdziłem, że niezbyt się to nadaje do użytku.

Poza tym, przeszedłem na Pythona, więc pomyślałem o małej rozgrzewce. Pierwszym pomysłem było przeparsowanie całego feeda i złożenie RSS. Znalazłem przykłady parsowania XML z użyciem beautifulsoup4, z którego zresztą trochę wcześniej korzystałem. Wyciąganie zawartości poszczególnych postów poszło bardzo dobrze.

Stwierdziłem, że zamiast się bawić w tworzenie feedu kolejnym modułem, w ramach eksperymentu dodam przy pomocy chamskich printów nagłówki od XML. O dziwo zadziałało, Firefox widział coś, co wyglądało prawie jak oryginał. Jedynym problemem było kodowanie - zdecydowanie był problem z pl-znakami. Rzecz w tym, że Blox używa iso-8859-2, a Python wypluwa UTF-8. Wystarczyła szybka zmiana deklaracji kodowania w nagłówku XML i już było OK.

Kolejny problem wyszedł przy przepuszczeniu feeda przez validatory feedów RSS. Okazało się, że beautifulsoup4 zamienia wszystkie znaki w tagach na lowercase i - wierząc szybkiemu sprawdzeniu - nie ma prostego sposobu, by go od tego odwieść. Podjąłem próbę zamiany moduł na inny, ale szybko zrezygnowałem na rzecz brzydkich, ale skutecznych sedów na wyniku działania skryptu.

Na koniec zostało dodanie wywołania (z użyciem utworzonego na tę okoliczność virutalenv) do crona:

*/15 * * * * /home/rozie/dsp2017/bin/python /home/rozie/rss_from_category_blox.py 2>/dev/null | /bin/sed s'/pubdate/pubDate/g' | /bin/sed 's/lastbuilddate/lastBuildDate/g' > /tmp/dsp2017.xml && /bin/mv -f /tmp/dsp2017.xml /var/www/dsp2017.xml
*/15 * * * * /home/rozie/dsp2017/bin/python /home/rozie/rss_from_category_blox.py 2>/dev/null > /tmp/dsp2017.xml && /bin/mv -f /tmp/dsp2017.xml /var/www/dsp2017.xml

Całość wrzucam na GitHub, na wypadek, gdyby miało się komuś przydać.


UPDATE: Zgodnie z sugestią z komentarza, parsuję XML prawidłowo i pozbyłem się sed poprawiającego wyjście.

© Pomiędzy bitami
Blox.pl najciekawsze blogi w sieci