2012
11.20

Część 1

Mamy już szkielet bota, ale taki bot powinien być łatwy w rozszerzaniu a trzymanie wszystkiego w jednym pliku nie jest szczególnie czytelne, spróbujmy więc rozbić go na rdzeń i moduły dostarczające content.

bot.pl v0.0.2

Ścieżka do modułów + helper dostarczający wygodnego ‘load $module_name’

use lib './lib';
...
use Module::Load;

Tutaj wczytujemy listę modułów z configa i przekazujemy im parametry.
Przy okazji zapisujemy wynik metody ‘info’ która posłuży nam jako opis modułu w helpie

39
40
41
42
43
44
45
46
my $module = {};
while (my ($name, $module_config) = each %{ $cfg->{'modules'} } ) {
    my $modulename = 'XANi::Infobot::Agent::' . ucfirst($name);
    load $modulename;
    my $m = $modulename->new($module_config);
    $module->{$name}{'info'} = $m->info();
    $module->{$name}{'handler'} = $m;
}

(more…)

2012
11.08

Jakiś czas temu zacząłem bawić się AnyEvent , jest to perlowa biblioteka która z jednej strony jest wrapperem do paru event loopów, a z drugiej strony oferuje zeventowizowane funkcje jak timery czy asynchroniczne I/O.

Jednym z modułów jest AnyEvent::XMPP::Client i grzebiąc trochę w jego przykładach postanowiłem naklepać sobie prostego bota
(more…)

2012
06.16

Niedawno dorwałem wreszcze rPi i po wrzuceniu Debiana na kartę SD zacząłem grzebać w /proc i /sys
Wychdozi na to że LED OK można kontrolować bezpośrednio spod /sys

# cd /sys/bus/platform/devices/leds-gpio/leds/led0
# cat trigger
none [mmc0]

Czyli domyślnie będzie migać przy IO na karcie

# echo none >trigger
# echo 0 >brightness
# echo 1 >brightness

I działa ;]. Wygląda na to że jest “źle” podłączona bo przy wysyłaniu 0 diodka się zapala a przy 1 gaśnie, prawdopodobnie bo woleli żeby indykator OK był głównie włączony.

2012
01.07

Od jakiegoś czasu używam varnisha jako cache dla mojego bloga i sprawdza się genialnie, dla rzeczy zcachowanych ( a przy odpowiednim configu to >90% ) czas odpowiedzi to właściwie RTT między klientem i serwerem. Nie jest skomplikowany w konfiguracji a przyśpiesza stronę paredziesięciokrotnie :).

Przygotowanie

Konfiguracja

Dp konfiguracji Varnish używa własnego minijęzyka zwanego VCL, odrobinę podobny do C. Pozwala on na grzebanie w nagłówkach zapytania i odpowiedzi oraz kierowanie requestu gdzie trzeba + parę innych akcji takich jak purgowanie obiektów w cache

VCLki mogą być przeładowywane w locie dzięki czemu nie traci się cache przy przeładowaniu configu.

Varnish domyślnie cachuje tylko w RAM, można mu wskazać cache dyskowy ale zostanie on zdiscardowany po restarcie (bo varnish go po prostu mmap()uje i traktuje jak kawałek pamięci, zostawiając OSowi co z tym fantem ma zrobić).

Istnieje opcja zapisywania cache na dysk, polega ona na tym że varnish podczas pracy streamuje obiekty na dysk a po restarcie zapełnia nimi cache, ale jest to rozdzielne z dyskowy cache – persisten storage podczas pracy jest tylko zapisywany, varnish nie serwuje z niego obiektów.

Konfig jakiego używam u siebie (pominąłem sekcje dot. backendów):

(more…)

2011
08.21

export DBI_TRACE=1=dbitrace.log
Gdzie 1 – debug lvl (1 całkowicie wystarcza, daje dane nt. wykonanych query i ich parametrów oraz create/destroy obiektów DBI) a dbitrace.log ofc plik do którego bedzie to logowane ;]

2011
08.12

Yes it works :]

W sumie jedna z tych rzeczy typu “Doh, czemu ja na to nie wpadłem” ;] Źródło: http://hackaday.com/2011/08/11/how-to-put-your-logo-in-a-qr-code. Tak kolorem też się da ;]

2011
08.02

Regexpy słyną z bycia językiem “tylko do zapisu”, często ciężko jest odcyfrować co autor regexpa miał na myśli. Jest (w perlowych i kompatybilnych) pewien ficzer który to ułatwia, mianowicie opcja x, powoduje ona że parser regexpów ignoruje komentarze, czyli taki np. dekoder daty (tak wiem że są liby, to tylko przykład ;))

my ($year, $mon, $mday, $hour, $min, $sec) = $date =~
  /(\d{1,4})\-(\d{1,2})\-(\d{1,2})\s+(\d{1,2})\:(\d{1,2})\:(\d{1,2}).*/;

można zapisać w formie:

my ($year, $mon, $mday, $hour, $min, $sec) = $date =~
  /(\d{1,4})\- # year-
   (\d{1,2})\- # month-
   (\d{1,2})\s+ # day + whitespace
   (\d{1,2})\: # hour:
   (\d{1,2})\: # min:
   (\d{1,2}) # sec:
   .* #rest of crap
  /x;

Trzeba tylko “wyescapować” wszystkie spacje (chociażby przez \s co oznacza “any whitespace” czyli też taby i \n)

Z innych przydatnych rzeczy to ściąga i edytor z tych “mniej znanych a przydatnych” :

  • (?:...) – pasywna grupa tzn matchuje ale nie będzie zwracane do zmiennych, czyli np (?:foo|bar)(.*) zwróci w zmiennej tylko zawartość bloku (.*) a nie foo/bar
  • \s i pokrewne, zamiast pisać \ (backslash spacja) czytelniej jest użyć \s które dodatkowo zmatchuje nam też taby i pare innych niewidocznych znaczków. \s+ jest przydatne, “matchuj jeden lub więcej whitespace”
  • {x,y} – zmatchuj od x do y znaków – np \d{3,} – więcej niż 3 cyfry, \S{5,9} – od 5 do 9 “nie-whitespace”
  • ? – powoduje że match będzie “ungreedy” czyli “zmatchuj minimalną liczbę znaków która będzie pasować, np gdy wrzucimy ciąg znaków “a:b:c” do regexpa (.*)\:(.*) to dostaniemy matche ‘a:b’ i ‘c’, gdy zrobimy matcha (.*?)\:(.*) na tym samym tekście to wynikiem będzie ‘a’ i ‘b:c’

Inną metodą na tworzenie regexpów jest “pokaż swojemu kotu jaki tekst chcesz zmatchować a potem posadź go na klawiaturze” ale to troszeczkę mniej czytelne ;]

2011
07.16

Po pierwsze – aptitude zamiast apt-get – ma trochę bardziej sensowne domyślne i przy instalacji wielu paczek łatwiej jest rozwiązać ew. konflikty na poziomie ncurses UI niż w CLI.

Chociażby dlatego że domyślnie nie usuwa “automatycznie” zainstalowanych paczek jak np. liby danej aplikacji ( nowa wersja apt-get informuje o tym z hintem żeby zamiast apt-get remove użyć apt-get autoremove – ale to troche mniej wygodne :)). O pinningu już pisałem

Polecam  http://www.debian.org/doc/FAQ/ch-customizing.en.html m.in jak podmienić plik z paczki na coś własnego tak żeby manager paczek go nie nadpisał podczas update paczki (p11.8) czy zarządzanie alternatywami

Z tego co używam na codzień w aptitude:

  • Wyszukiwanie ( klawisz / ) obsługuje regexpy (doh)
  • C pokaże changelog danej paczki
  • Po wejściu (Enter) w szczegóły paczki na dole można wybrać wersję (niby banał, ale widziałem ludzi klepiących apt-get po wyjściu z aptitude ;)
  • f (zapomnij o nowościach) wyczyści spamkategorie “Nowe pakiety”
  • Powyższe można zautomatyzować klikając w Opcje -> Preferencje ;)
  • Warto przejrzeć te menu – są tam tak przydatne funkcje jak np. “Anuluj zaplanowane zadania”

Oraz ofc etckeeper – od razu widać jakie zmiany w domyślnym configu wprowadziła paczka i czy to nasz fail czy paczki; można łatwo zrobić rollback/diffa poprzedniej “działającej” wersji.

Na koniec jeżeli używasz też (praca/testy/whatever) centosa lub pochodnych:

alias apt-cache=yum
alias apt-get=yum
alias aptitude=yum

bo inaczej będziesz klepał apt-get w centosie i yum w debianie ;].

2011
07.10

W życiu każdego admina przychodzi moment w którym trzeba umieścić cholernie niedorobiona niezbyt dobrze napisaną aplikację na serwerze i okazuje się że ta aplikacja po jakimś czasie zaczyna wariować. Czy to zwiecha czy wpada w pętlę i żre procesor jak szalona czy po prostu cieknie i po jakimś czasie zżera cały RAM i OOMkiller mówi “that’s a good day for you to die”, trzeba znaleźć sposób żeby dalej chodziła (bo nie ma alternatywy/nie da się naprawić/whatever).

Standardowym podejściem jest albo napisanie skryptu-niańki sprawdzającego czy działa poprawnie i zajmującego się resetem (w przypadku gdy app wpada w deadlock czy cieknie) lub prosty restart po padzie, czy używając while sleep 1 ;do /some/where/app ; done czy supervisora typu np. daemontools.

Gdy potrzebny jest prosty restart to nie jest problemem, schody zaczynają się gdy trzeba napisać więcej warunków.  Z czasem dochodzi potrzeba dodania więcej ficzerów np. alerty na maila w wypadku restartu, sprawdzanie danego URLa czy app działa, więcej testów itd. Potem pojawia się inna aplikacja, copy-paste starego skryptu, parę zmian, znowu dopisywanie nowych rzeczy (bo np. chcemy powiadamiać programistę o padzie ale tylko tej aplikacji, albo chcemy żeby dostawał maila tylko jeżeli restart się nie powiedzie). Jeżeli tego będzie wystarczająco dużo to pewnie nasz skrypcik spotka rewrite żeby obsługiwał pliki konfiguracyjne, stronę statusu, więcej testów itd.

Guess what ? Ktoś już to zrobił ;]

(more…)

2011
06.06

Mam sobie modem od tepsy, model ZXDSL 831A. Pewnego dnia postanowiłem zrobić mu autoreboot (żeby mi Neo nie rozłączało w środku dnia tylko w środku nocy) i po chwili wiresharkowania doszedłem do curl -u admin:admin http://10.254.254.1/rebootinfo.cgi , wrzuciłem do crona i zostawiłem modem w spokoju.

Ale gdy zacząłem grzebać przy nim podczas pisania tutoriala udało mi się znaleźć coś ciekawego, mianowicie modem można zresetować bez podawania hasła, curl http://10.254.254.1/rebootinfo.cgi owszem, zwraca Permission Denied, ale router i tak strzela reboot. ;]

Na szczęście resetowanie do ustawień fabrycznych w ten sposób nie działa (chociaż nie grzebałem długo) ale fail to fail. Prawdopodobnie inne modele tego samego producenta mają podobny fail, może ktoś potwierdzić