Sunday, October 27, 2024

CTF Hack The Boo Practice & Competition 2024

Ostatnio koleżanka z pracy zaraziła mnie rozwiązywaniem CTFów. Założyłem sobie konto na https://ctf.hackthebox.com/ i rozpocząłem swoją przygodę z Capture The Flag.

Coding

Replacement

Tutaj postanowiłem użyć Python'a.

inp = input()
rep = input()
rep_with = input()

print(inp.replace(rep, rep_with))

MiniMax

Ponownie użyłem Pythona.

inp = input()

l = [float(num) for num in inp.split(' ')]

print(min(l))
print(max(l))

CTF Hack The Boo Practice

Web

Void Whispers

Chciałem opisać jeszcze jedno zadanko, z którego jestem szczególnie dumny.

Pierwsza rzecz, którą zauważamy to fakt, że do funkcji shell_exec zostaje przekazana zmienna $sendMailPath:




Tak więc można w prosty sposób wywołać coś w shellu. Problem polega jednak na tym, że chwilę wcześniej w liniiach 36-38 sprawdzany jest czy nie występują w payloadzie spacje.
Po kliknięciu przycisku Save generowany jest plik config.json, który możemy podejrzeć pod adresem http://localhost:1337/config.json.
Mój pomysł na rozwiązanie tego zadania to zrzucenie zawartości pliku /flag.txt do config.json.
Po pierwsze nasze nowe polecenie w linii 40 musi zfailować, aby program nie nadpisał pliku config.json. Drugi problem to brak spacji. Zamiast spacji można korzystać ze zmiennej ${IFS}. Tak więc wpisujemy w pole Sendmail PATH 

;cat${IFS}/flag.txt${IFS}>config.json

Średnik kończy polecenie which. Później zrzucamy zawartość pliku /flag.txt do config.json. Ponieważ polecenie nic nie zwróci program przerwie działanie w linii 42 nie nadpisze pliku config.json. Klikamy ponownie Save. Dostajemy komunikat błędu. Możemy teraz odświeżyć http://localhost:1337/config.json i podejrzeć flagę.

Saturday, November 19, 2011

Scala - scratch the surface

Nareszcie! Trafiłem na naprawdę fajne wprowadzenie do języka Scala, które ostatecznie dało mi posmak tego języka, zobligowało do za instalowania Scala IDE na komputerze i napisania kilku prostych klas, oraz fragmentu kodu.

Mowa oczywiście o Scala for Java Refugees Daniela Śpiewaka, żałuję tylko, że nie trafiłem na to trzy lata temu (wpisy są z 2008 roku), ale może to była też kwestia dojrzewania do tego języka? Nie wiem. Wiem jedno, że język jest naprawdę fajny, chociaż w przeciwieństwie do Rubego - to co napiszę zdarza się nie działać.

Język jest ogromny i jego poznawanie może mieć wyłącznie charakter stopniowy. Jest tego po prostu za dużo. Zresztą, każdy język programowania ma obszary, których nigdy nie potrzebowałeś, nie używałeś - Scala ma ich po prostu więcej.

Na razie jednak zaczynam pisać projekt w Rails-ach, a w świecie JVM przygotowuję się do Certyfikatu wydawanego kiedyś przez Sun, a teraz Oracle, dla programistów Java. Tak więc "mieszanie" sobie Scali z Javą może być niebezpieczne na tym etapie. Do następnego razu.

Thursday, November 17, 2011

PhantomJS i Ruby - czyli przygody małe i duże

No więc stało się. Jestem programistą Javy. I co z tego? A no trzeba w domu jakoś odreagować.
Na pierwszy ogień poszedł Ruby i to nie byle jaki jak 1.9.3-p0. Windowsowa paczuszka ściągnięta wprost z RubyInstaller ślicznie zadomowiła się w moim systemie operacyjnym, dając mi nawet w trakcie instalacji dodać poleceni ruby do ścieżki systemowej.

No ale nie o Rube-go chodzi tylko o chęć napisania jakiegoś drobiazgu z meta-programowaniem. No więc potrzebny jest edytor.

gem install redcar
redcar install
redcar
I moim pięknym oczom ukazał się turbo edytor RedCar - i od razu zrezygnowałem nawet z myśli o płaceniu za TextMate na Mac-u. Napisałem sobie bardzo prosty program, który pozwolę sobie dumnie nazwać klient "REST". Tak naprawdę to prawie na jedno by wyszło jakby podziedziczył po Net::HTTP, ale że miało być "meta-programowanie" to wyszło tak:


require 'net/http'
require 'uri'

class REST
def self.method_missing(m, *args, &block)
uri = URI(args[0])
Net::HTTP.start(uri.host, uri.port) do |http|
puts "Calling #{m} REST call."
return http.send(m.downcase.to_sym, uri.path)
end
end
end

res = REST.GET("http://www.google.pl/")
puts res.body


Nikt, nie mówił, że jest się czym chwalić, ale coś mnie tchnęło, żeby pobrać (a co) zawartość wyżej wymienionej strony w PhantomJS. Trwa to wieki i gdyby tak działała przeglądarka to pewnie zrezygnowałbym z Internetu, albo kazał, za korzystanie z niego, sobie płacić, ale ... na szczęście Google Chrome ładuje WebKit raz a nie za każdym razem gdy otwieram zakładkę - więc da się żyć. Na stronie projektu, gdy napisałem już skrypt w JavaScript zauważyłem, że mogę też podawać skrypty w CoffeeScript pominę więc moje wypociny w JS i podam odrazu wersję Coffee, a jak interesuje Cię co napisałem w JS to wklej sobie poniższą zawartość na stronie Try CoffeeScript i będziesz wiedział.

page = new WebPage()

if phantom.args.length == 0
console.log 'Usage: google.coffee some-url'
phantom.exit()
else
t = Date.now()
address = phantom.args[0]
page.open address, (status) ->
if status != 'success'
console.log 'FAIL to load the address'
else
t = Date.now() - t
console.log 'Loading time ' + t + ' msec'
console.log 'Page content is \n' + page.evaluate () ->
document.documentElement.innerHTML
phantom.exit()


Edytor kodu na Blogger jak zwykle daje ciała nie wspierając wstawek kodu źródłowego, ale co tam. Najgorsze, że RedCar nie ma wsparcia dla CoffeeScript, ale może się dorobi jak skończy być Alphą. No nic, czas kończyć. Na dziś starczy już tego dobrego wracamy do Thinking in Java, którego autor i tak co 100 zdanień kończy stwierdzeniem w stylu "Java to ogromny krok na drodze postępu w tej dziedzinie, ale Python i tak robi to lepiej."

P.S. Moim ogromnym odkryciem w Ruby było odkrycie, że każdy operator to metoda. Kiedyś nie mogłem znaleźć w dokumentacji co dokładnie robi ~= (czy tam =~) bo szukałem jakiegoś działu dokumentacji Ruby-Doc, który definiowałby operatory zamiast sprawdzić metodę =~ klasy String albo RegExp.

Friday, September 16, 2011

Sposób na zrywane sesje SSH

Nie wiem dlaczego, ale albo mój router, albo mój dostawca (UPC) wciąż zrywa nieaktywne sesje SSH. Nie ma mowy o zostawieniu Puttego w tle choćby na kwadrans. Po kilku minutach okno informuje mnie iż połączenie zostało zerwane i muszę wracać do mojej pracy ponownie. Frustrujące.

Jest na to sposób. Zostawienie otwartego w konsoli Screena, który na dolnym pasku wyświetla godzinę. Tak więc wpis:
caption always "%`$USER%`@%H: %{kg} %L=%-Lw%45>%{yk}%n%f* %t%{-}%+Lw%-0< %= %{yk}%c%{kg} load:%l"
w pliku ~/.screenrc właściwie załatwia sprawę. Kwestia startowania sesji podczas każdego logowania. Można to załawić dodając na końcu pliku ~/.bashrc
# Start or resume screen
if [[ -n "`screen -ls | egrep '\.default(.*)(Detached)'`" ]]; then
    screen -r default
elif [[ -n "`screen -ls | egrep '\.default(.*)(Attached)'`" ]]; then
    false
else
    screen -S default
fi

Monday, September 12, 2011

Internet i MMSy w Play na HTC Dream

Teoretycznie skonfigurowanie telefonu w play to wysłanie SMSa o treści "play" na numer 9999. Jeżeli posiadasz HTC nie jest to tak proste. Na moim HTC Dream wymagało to podjęcia następujących kroków:
Menu > Ustawienia > Opcje bezprzewodowe > Sieci komórkowe >  Punkty Dostępowe > Menu > Nowa nazwa APN


Internet


  • Nazwa: Internet
  • APN: internet
  • MCC: 260
  • MNC: 06
  • Typ APN: default


MMS

  • Nazwa: MMS
  • APN: mms
  • MMSC: http://10.10.28.164/mms/wapenc
  • Proxy dla wiadomości MMS: 10.10.25.5
  • Port MMS: 8080
  • MCC:260
  • MNC: 06
  • Typ APN: mms
Po zapisaniu uruchom ponownie telefon.

Saturday, September 3, 2011

Ruby On Rails 3.1 - dzień pierwszy

Zawsze uważałem, że najlepszy poradnik, to zbiór wskazówek pisanych przez początkującego, nie koniecznie zaś zapełniane przez mądrego człowieka annały, które jak na początek, mogą być za mądre. Równocześnie, najlepiej aby początkujący miał już doświadczenie z innymi podobnymi zagadnieniami  jednak w danej technologii był początkujący. Taki układ daje duże szanse, że poradnik będzie profesjonalny, pisany prostym językiem i zrozumiały dla maluczkich, którzy oczekują prowadzenia krok po kroku. Mam nadzieję, że moje wpisy o Ruby On Rails 3.1 takie właśnie będą.

Dlaczego?

Mam za sobą już, od jakiegoś czasu, Rails for Zombies, czytałem o Ruby On Rails i jeszcze nigdy nie spotkałem się z osobą, która zaczęłaby kurs Railsów od RVM. Podstawy podstaw - jak na mój gust.

Gdy piszesz jakikolwiek program, aplikację musisz zdecydować się na dwie rzeczy: wersję języka programowania i wersję pozostałych bibliotek, które używasz. U mnie to wygląda tak: zaglądam na stronę języka programowania (w tym przypadku języka Ruby), zaglądam na stronę biblioteki (w tym przypadku Railsów) i nakręcam się na napisanie aplikacji w najnowszej wersji, która wprowadza najświeższe udogodnienia, nowości, nowatorskie technologie i wszystko co sprawia, że bycie geekiem jest piękne i pełne wrażeń jak przejażdżka górską kolejką w parku "Six Flags Great Adventure".

Później przychodzi faza druga, która nazywa się "sprawdźmy co jest na serwerze" i ta przynosi znacznie więcej rozczarowań, niż radości dopóki nie używasz ArchLinux lub nie jesteś twórcą biblioteki, której właśnie zamierzasz użyć. Wtedy klniesz pod nosem, że "przecież administrator mógł przejść na sida" i jakbyś tylko miał uprawnienia użytkownika root!
I tutaj właśnie objawia się piękno RVM. Pozwala ono bowiem bez uprawnienia super-użytkownika zainstalować dowolne wersje języka Ruby, w locie podmieniać interpreter oraz wersje używanych bibliotek, które w wielu różnych kombinacjach mogą koegzystować w wirtualnych środowiskach zwanych gemsetami. Wszystko bez wychodzenia poza katalog domowy.

Friday, August 26, 2011

Jak korporacje dobierają narzędzia

Ten post jest próbą wyrzucenia z siebie drzemiącej głęboko frustracji dotyczącej fatalnego podejścia do doboru narzędzi, w korporacjach, z którymi się zetknąłem.

Trawestując znanego survival-owca oraz Naczelnika Skautów Wielkiej Brytanii "Narzędzia są po to aby wykonywały pracę za Ciebie - nie na odwrót.". Choć zdanie to dotyczyło konserwacji i ostrzenia piły, noża czy siekierki, to pasuje również do naszej, jakże przepełnionej narzędziami, informatycznej rzeczywistości.

Rozpoczynając pracę musisz wybrać narzędzia. Jednak samo ich posiadanie nie rozwiązuje problemu - musi nastąpić etap selekcji. Selekcji, która w dużych firmach podejmowana jest raz i nieodwołalnie, często kilka, anawet kilkanaście lat przed rozpoczęciem projektu, któremu przyjdzie z nich korzystać.

Innymi słowy, narzędzia wybierane są globalnie w skali całej firmy i w tej samej firmie ich używanie jest egzekwowane bez względu na charakter i rodzaj przedsięwzięcia. Zdarza się iż używany jest system kontroli wersji, którego początki pamiętają roku 1992, którego założenia koncepcyjne są na tle nowoczesnych systemów kontroli wersji z gruntu złe. Ogromna ilość pieniędzy, stworzona infrastruktura, ilość znanych rozwiązań problemów oraz doświadczenie tworzą pozorną wartość przekładającą się na równie pozorną łatwość w użyciu tak dobrze "sprawdzonego" i "sprawdzającego się" narzędzia w kolejnym projekcie.

Jednak wszystko to jest iluzoryczne. Przyzwyczajenia ludzi nie świadczą o jakości narzędzia, ani o sprawności jego używania gdyż nawet większa nieudolność, w wykorzystywaniu nowego oprogramowania na początku, może być błyskawicznie zniwelowana sumą zwiększonej prędkości jego działania oraz dobrze przygotowanym programem szkoleń dla osób początkujących, posuniętego nawet do algorytmów postępowania.

Równie fałszywe jest wrażenie "problemów, z którymi przyjdzie nam się zmierzyć". Często zakładamy, że skoro oprogramowanie zaproponowane przez firmę sprawiło nam wiele kłopotów, to wraz z wprowadzeniem nowego narzędzia pojawią się nowe. Nikt jednak, bardzo często, nie zauważa, że znaczna część tych problemów wynika z wieku narzędzia i architektury oraz koncepcji, które bardzo często nie przystawały do współczesnych realiów. Realiów, w których zostało stworzone nowe narzędzie, dzięki któremu będziemy mogli zminimalizować portfolio "dobrze znanych rozwiązań, dobrze znanych problemów" nawet o 90%.

W epoce kamienia łupanego ludzie do krojenia używali ostrych kamieni. Używali ich ponieważ sprawdzały się, a w pobliżu nie było nic bardziej dostosowanego do krojenia. Dzisiaj jednak używamy noży, toporów, siekier, pił i scyzoryków. Używamy ich na drodze prostej ewolucji, w której narzędzia mniej przydatne przestawały być używane, odchodziły w niepamięć, a zastępowały je lepsze, bardziej użyteczne odpowiedniki. O tym czy narzędzie i jego wykorzystywanie przetrwało do naszych czasów czy nie decydowała jego efektywność.

Kiedy się temu przyjrzymy, wydaje się to rzeczą naturalną. Można wręcz powiedzieć iż stwierdzenie przybliżone w poprzednim akapicie trąci truizmem. Truizm ten nie jest niestety oczywisty w korporacjach, w których w kółko i na okrągło wykorzystuje się stare, zakupione dekadę, albo dwie temu programy. Pomimo dziesiątek problemów i dawno stwierdzonych wad są używane w kolejnych projektach.

Jednak nie tylko wykorzystywanie archaicznych rozwiązań, na dużą skalę, może być błędem. Git to niewątpliwie fantastyczny system kontroli wersji. Pomyli się jednak ten, kto użyje go do projektu Visual Studio 2010, w środowisku opartym o kontroler domeny Windows. Wystarczy bowiem przyjrzeć się Mercurialowi aby dostrzec zalety w formie: natywnego wsparcia dla okienek, świetnej integracji z Visual Studio 2010 dzięki wtyczce VisualHG (znacznie lepszej niż jakakolwiek integracja Gita z Visualem), czy wsparcia dla Single Sign On w postaci HGKerberos, która działa z SPNEGO.

Na tym przykładzie widać, że narzędzia można dobrać lepiej lub gorzej, albo po prostu źle. Moim zdaniem idealnym rozwiązaniem jest tworzenie architektury "per-projekt", w których używane narzędzia będą symbolem "epoki", w której projekt startował. Doskonale rozumiałbym używanie tak archaicznego systemu kontroli wersji jak CVS w projekcie z lat 90siątych, tak jak używanie Subversion w narzędziu, którego początki są datowane na 2000 rok. Konsekwentnie, dobierając nowoczesne rozwiązania do projektów, które powstały na przestrzeni kilku ostatnich lat.


Saturday, August 20, 2011

Świetny program do robienia screenów pod Windows

Zawsze zachwycały mnie screeny prezentowane w sieci przez użytkowników komputerów Mac. I nie chodzi mi o cukierkowy interfejs OS X, ale o ładnie opisane, zaznaczone, wskazane przejrzystymi strzałeczkami elementy.

Zacząłem szukać oprogramowania pod Windows, nawet płatnego, który pozwoliłoby tworzyć równie schludne obrazy, pozwalając na nanoszenie strzałek czy napisów.

Początkowo, wraz z wydaniem Windows 7, zwrócił moją uwagę program "Narzędzie Wycinanie" dostępny wraz z systemem operacyjnym. Był to pierwszy raz kiedy do robienia zrzutu ekranu nie używało się guzika Print Screen, a wykorzystywanym programem wcale nie był Paint.

Pomimo znacznie podwyższonej wygody korzystania możliwości "Narzędzie wycinanie" nie zachwycały. Kilka miesięcy później trafiłem na Screenpresso. O kupnie programu myślałem już nie raz jednak żadna z dostępny po zapłacie opcji nie jest mi do szczęścia potrzebna i darmowa wersja w stu procentach spełnia moje potrzeby i oczekiwania.

Po zainstalowaniu program podpina się pod klawisz PrintScreen przyciemniając ekran i dając nam możliwość wyboru obszaru, który chcemy umieścić na zrzucie. Już na tym etapie otrzymujemy dwa udogodnienia: małą lupkę w prawym dolnym rogu ekranu, która pozwala nam dzięki powiększeniu precyzyjnie dobrać współrzędne prostokąta oraz szalenie użyteczny detektor kontrolek Windows, który po najechaniu zaznacza jej obszar sugerując nam wykonanie screenshotu tego konkretnego okna, pola, przycisku czy obszaru.

Chwilę później możemy już skopiować zawartość zrzutu [CTRL]+[SHIFT]+[C], plik ze zrzutem [CTRL]+[C], zmienić nazwę pliku [F2] czy usunąć nasze dzieło [DEL]. Najciekawszą opcją jest otworzenie zrzutu w wewnętrznym edytorze [ALT]+[E].

Opcji dostępnych w otworzonym przed chwilą oknie nie powstydzi się nawet użytkownik MacOSX. Program pozwala nam:
  • nanosić strzałki
  • tekst
  • zaznaczać eliptyczne lub prostokątne obszary
  • dodawać dymki i ikony
  • numerować punkty
  • podświetlać lub zamazywać fragmenty obrazu
Wszystkie elementy wyglądają szalenie elegancko i schludnie a efekt końcowy naprawdę cieszy oko.

Jeżeli nie wystarcza nam zaznaczanie obszaru ScreenPresso oferuje wykonanie screenshotu poprzednio użytego regionu, całego ekranu lub wykonanie zrzutu tuż po puszczeniu paska przewijania jednego z okien.

Edit
W myśl dewizy "zarabiam - płacę" zakupiłem wspomniany program w celu odblokowania opcji kręcenia filmików dłuższych niż, dostępnych w wersji darmowej, 15 sekund.

To co mile zaskakuje - nie musimy ujmować na filmie całego ekranu - możemy wyznaczyć obszar, który zostanie ujęty na filmiku. Niestety, to wszystko co oferuje obecnie w tej materii ScreenPresso. Nie znajdziemy tu żadnych zaawansowanych efektów, możliwości podświetlania i zaznaczania, przejść czy podążania za kursorem - mam jednak nadzieję, że to czasowe :)

Po nakręceniu filmiku jest on zapisywany w formacie zrozumiały wyłącznie dla wewnętrznego edytora. Aby udostępnić pozostałym nasze dzieło musimy korzystać z opcji konwersji. Tutaj nie możemy narzekać na brak możliwości: MP4, WebM, OGV, WMV czy witryna HTML5. Podążanie za trendami twórców oprogramowania aż zaskakuje.

Każdemu kto tworzy wiele instrukcji i szuka dobrego programu do ubogacania jej zrzutami serdecznie polecam!

Saturday, June 18, 2011

Języki ponad-maszynowe

Odnośnie poprzedniego wpisu, moim zdaniem świat programistyczny powinien zainwestować więcej uwagi w kierunek jaki obrał chociażby PyPy czy Rubinius. Implementacje języków programowania, które są niezależne od maszyny wirtualnej, z której przyjdzie nam korzystać.

Pewne uniwersalna rodzina dialektów, które możemy wybierać do potrzeb danego zagadnienia nie zastanawiając się czy nasza aplikacja będzie działała na Androidzie, Linuksie, czy MacOS X. To jest moim zdaniem przyszłość.

Jeżeli o maszyny wirtualne chodzi - można zaobserwować ciekawe zjawisko. Pewien szczególny rodzaj maszyny wirtualnej, dostępnej wszędzie wytworzył się "przypadkiem". O dziwo jest nią przeglądarka internetowa. Połączony z tym rozwój takich standardów jak HTML5, CSS3 i projektów z nimi powiązanymi, problemy z technologią Flash na platformach mobilnych sprawiły, że dzisiaj przeglądarka internetowa/sieć jest najczęściej wybieraną platformą do tworzenia oprogramowania. Jeżeli już dziś chcemy napisać oprogramowanie, która za 20 lat będzie działało na kaczuszce do kąpieli naszego dziecka - zaimplementujmy to w JavaScript. Dzięki CoffeeScript, SprouteCore, ExpressJS, NodeJS JavaScript przychodzi pod strzechy. Za nią zaś stoją niewyobrażalnie zoptymalizowane maszyny wirtualne, które są od lat tuningowane i wystawiane do prezentowania swoich możliwości na torze zwanym Internet. Tutaj nie ma miejsca na pozorne rozwiązania - współzawodnictwo jest zacięte, a konkurencja nie śpi.

Może się wydać to nietypowe. Każdy język programowania posiada jedną maszynę wirtualną, stworzoną dla niego - JavaScript posiada ich aż kilka. Gdyby nie CoffeeScript - to z jej ohydną składnią i obleśną semantyką ociekającą toną wtfjs byłaby jak rozprzestrzeniające się na ogromną skalę trucizna. Na szczęście ludzie zaczęli ją oswajać i powoli uczą się ją wykorzystywać do tworzenia leków, znaleźli już wiele ciekawych zastosować.

Rodzi się pytanie - czy i jak JavaScript będzie można sprzedać? Język programowania, wykorzystywany do tej pory "dla bajeru", przez domorosłych informatyków, używany do pisania małych fragmentów, wstawek kodu staje się kompletnym rozwiązaniem z armią, przez lata optymalizowanych w wyścigu "zbrojeń" maszyn wirtualnych w drugim szeregu.

Język, w którym nie jest znana mi żadna metoda dająca zaczepienie oprogramowaniu "closed-source", gdzie jedyną metodą "chronienia" kodu jest jedynie jego zaciemnianie. Czyżby polimorfizm znany z pierwszych lat tworzenia wirusów? Zobaczymy.

Java w nowych projektach i racja jej bytu.

Czas języków programowania dawno minął - nastał czas dialektów maszyn wirtualnych.

Od kilku dni w firmie zatrudniani są programiści języka Java. Po rozmowie z zatrudniającymi managerami załamałem się - bo niby dlaczego Java?

Pisząc aplikację dla platformy Android, czy rozwijając Rational Team Concert to czego potrzebujesz to - plik wynikowy, zrozumiały dla JVM, napisany w konkretnej konwencji, używający konkretnych bibliotek a nie Java!

Jakie miejsce powinni zajmować dziś programiści C++ czy Java? Rozwijać dalej istniejące, dobrze napisane, oprogramowanie.

W dzisiejszych czasach możemy mówić o dialektach maszyn wirtualnych. Ślepe wybieranie dialektu języka Java do pisania oprogramowania dla JVM to po prostu zaściankowość i ciemnota.
Wiele innych: Clojure, jRuby, Jython, Noop czy chociażby Scala - mogą w danym zastosowaniu znacznie skrócić czas kodowania, podwyższyć jakość oprogramowania, obniżyć stopę występowania błędów, znacznie zwiększyć jakość kodu. W skrócie: skoro może być szybciej i lepiej to po co trzymać się języka Java? Trawestując Martina Klepmann : "Modern language programming is good 'quality filter' for people."

Oczywiście: nadal istnieje wiele powodów, dla których utkniemy z kolejnym projektem w języku Java. Brak developerów danego języka na rynku to podstawowa przyczyna - choć może być ich więcej. Moim zdaniem należy jednak próbować, podejmować wyzwania i ryzykować bycie innowacyjnym - to się opłaci.

Friday, May 27, 2011

Continous integration i Python?

Czy ktoś widział może kiedyś budowanie projektu pisanego w Pythonie?
Może nie jestem czegoś świadom, albo myślę zbyt szablonowo ale: continous-integration jest dobrze zdefiniowane dla projektów, które trzeba kompilować. Wiadomo. Developer nie kompiluje kodu sam. System CI sam sprawdza za niego czy kod pozytywnie przechodzi etap kompilacji i wysyła powiadomienia.

Ale jak odnieść się do tego w świetle Pythona. No dobra, wyciągamy kod źródłowy z repozytorium - i co? Przecież go nie skompiluję. Wszystko, na stać moją wyobraźnię na dzień dzisiejszy, to hmm... scan pylint, pychecker, pep8, odpalanie metody .compile() na każdym module? Jeżeli już zdecydujemy się na skany: to jak zachować się w przypadku jakiś komunikatów. Kod nie musi być źle napisany, zresztą zakładamy, że przeszedł review, ale wtedy co? Sfailować build tylko dlatego, że kod Pythona programisty nie odpowiada pylint. To niczego nie udowadnia.

Piszę ten post w związku z sytuacją jaka miała miejsce kilka dni temu. Rozumiem, żeby w trakcie budowania projektu Pythonowego odpalać testy w ramach. W moim przypadku nie mam nawet czasu aby je pisać więc nie ma co odpalać. Przyjmuję argument, że to co wychodzi na produkcję powinno być numerowane. To bardzo pomocne i użyteczne. Jednak w Python 2 wszystko co sobie wyobrażam to otagowywanie kolejnych wersji w repozytorium. Podmienianie egga, który wywala serwer Apache ponieważ przestają mu się zgadzać sumy kontrolne - to jakaś porażka. To nie wiem co innego mógłbym robić? Dodawać komentarz z numerem buildu w jakimś umówionym pliku? Dodam jeszcze, że to aplikacja internetowa pisana w Django.

Jeżeli ktoś jest w temacie to jestem bardzo zainteresowany wymianą doświadczeń w tym temacie.

Webdevelopment i unit testy

Kilka tygodni temu zacząłem developować webowy frontend dla projektu gitolite o nazwie glboard. Gitolite to warstwa abstrakcji pozwalająca na kontrolę dostępu do repozytoriów systemu git podczas dostępu do serwera przez ssh.

Glboard od samego początku pisany był z myślą o testach, dlatego wraz z kodem publikowane były unit testy do udowadniania poprawności metod, klasy, która stanowi trzon funkcjonalności.
Podczas oglądania prelekcji "State of Pylons/Turbo Gears2/repoze.bfg", moją uwagę przykuły zarzuty postawione unit testom w web-developmencie.

W tym okresie spędziłem sporo czasu, w glboard, na poprawianiu unit testów. Jeżeli padłem ofiarą zbyt wczesnego testowania - to jaki sens ma Test Driven Development?
Podczas zmieniania głównej klasy, obsługującej operacje na repozytorium gita, uzyskałem pewien ciekawy efekt - witryna działała i mogłem dzięki niej wykonać wszystkie operacje - natomiast testy failowały. Wszystkie. Powód był prosty: klasa przyjmowała teraz nowy argument w metodzie __init__.

Wspomniana prelekcja uświadomiła mi jedną rzecz. Jeżeli nie wystawiasz czegoś na zewnątrz, nie wystawiasz API lub biblioteki, nie będziesz zobligowany do zachowywania wstecznej kompatybilności z jakimś stworzonym przez siebie interfejsem, które kiedyś udostępniłeś, tylko dlatego, że używają go klienci - nie używaj unit testów. Pisanie unit testów do elementów, które zostają w twoim projekcie i nie wychodzą w żaden sposób na zewnątrz - to strzelanie sobie w stopę.

Moim zdaniem pisząc aplikację we frameworku webowym to co powinno się testować - to działanie przez przeglądarce. Testy funkcjonalne wydają się wystarczające. Może są troszkę bardziej kosztowne niż unit testy, ale w gruncie rzeczy, dobrze napisane, testują dokładnie to co powinny. Nie skupiają się na API konkretnej klasy, funkcji, metody, ale na tym czy witryna działa - nie ważne jest jak.

Odnosząc się do narzekań na Selenium i długiego czasu trwania testów w nim napisanych: myślę, że możemy spodziewać się rewolucji w świecie testów web-aplikacji dzięki PhantomJS. Nie znam jego wydajności, ale funkcjonalność jest w tej dziedzinie bardzo obiecująca i daje znacznie więcej możliwości niż zwykłe funkcyjne testy. Równocześnie nie używa całego niepotrzebne osprzętu jakie ładuje przeglądarka.

Wszystko co w tej chwili mi pozostaje to usunąć unit testy z glboard i napisać functional testy :)

Saturday, February 26, 2011

Co w językach programowania i web developmencie piszczy

Od czasów, kiedy skończyłem studia bardzo interesowałem się rozwojem języka C++. Na początku bibliotkę Boost, w której ląduje co ciekawsze pomysły, które mają w przyszłości zagościć w języku a potem wersją C++0x. Dzisiaj spojrzałem na wsparcie dla składni C++0x w gcc-4.6 i powiem szczerze, że nie mogę się doczekać kiedy Ubuntu i Debian zostaną skompilowane na tym właśnie kompilatorze. Na razie nie jest dostępny na żadnej dystrybucji - niestety brak go również w paczkach Ubuntu 11.04, ale użycie tego kompilatora będzie szalenie ekscytujące.

Lista wszystkich zaimplementowanych nowinek jest dostępna tutaj: http://gcc.gnu.org/gcc-4.6/cxx0x_status.html

Mnie cieszą dwie: składnia dla for znana z python - gdzie iteruje się po elementach, nie po indeksach oraz lambdy - czyli funkcje nienazwane, które można przekazywać jako parametry.

W sumie powiem szczerze, że mam szaloną chęć napisać coś w C++ :) na przykład stronkę - jest framework Web Toolkit więc czemu by nie spróbować :] Jak się patrzy na listę możliwości to pojawia się UTF-8 i 16, HTML 5 native, async I/O, VML, SVG, PDF, PNG/GIF, SSL, TLS właściwie wszystko czego dusza zapragnie, a czym nie chwalą się żadnej inne frameworki należące do języków skryptowych, które borykają się z różnymi problemami w tej dziedzinie (ostatnio szczególnie frameworki Pythonowe). Można deployować przez FastCGI, postawić na dedykowanym serwerze dostarczonym z frameworkiem albo podpiąć do IIS. Brzmi super :)

C++ staje się naprawdę fajnym językiem, może mniej fajnym niż Go (z frameworkiem web.go) :) ale naprawdę wartym uwagi. Pozostaje czekać tylko czym będzie język Noop i cieszyć się z tego co przyniosą najbliższe lata :)

Jeżeli zaś ktoś chciałby popróbować development na wirtualnej maszynie to przychodzą mi na myśl wyłącznie Lift z języka Scala i z troszkę innej beczki :) ExpressJS dla języka Node.JS.

Jako ciekawostkę dodam, że jeżeli ktoś chce się nauczyć, w jakimś subiektywnym aspekcie języka "idealnego" to istnieje świetny kurs do języka Haskell pod tytułem "Learn You a Haskell for Geate Good!" . Web Development też jest wtedy możliwy - dzięki frameworkowi Snap.

O zapomniałbym. Ostatnio (no już trochę czasu minęło) Zed Shaw stworzył (ten gość chyba się po prostu nudzi) Tir - framework do web developmentu w języku skryptowym Lua. Co więcej wszystko w ramach projektu Mongrel2, który jest jeszcze bardziej imponującą kontynuacją znanego developerom Ruby On Rails serwera Mongrel - tym razem, w drugiej wersji wspiera chyba każdy język programowania.

Przy okazji - dla tych, którzy siedzą wciąż w świecie Python i Ruby. Jeżeli szukacie jakiegoś hiper wydajnego frameworka to nie tylko najnowszym i najnowocześniejszym w architekturze, ale również ewidentnie najszybszym jest Pyramid - jeżeli wierzyć wynikom z artykułu "The great web technology shootout – Round 4: Pyramid vs Django vs TG vs Rails 2 & 3" - bije na głowę dosłownie wszystko. Jednak jest to framework stricte w filozofii i podejściu wykorzystywanym w Pylons - i jego sukcesorem. Co miłe jest to "najszybciej wydany" framework w dziejach macro-frameworków jakie w życiu widziałem bo development zaczął się w Grudniu 2010 a pod koniec Stycznia 2011 wyszła stabilna wersja 1.0 - chociaż to troszkę naciągane bo projekt nie startował od zera ale był adaptacją już wcześniej wydanego Repoze BFG.

Zdradzę jeszcze, że dowiedziałem się iż na PyCon 2011 US, który odbywa się w Marcu odbywają się sprinty, które mają na celu portowanie Pyramid na Python 3 tak więc możemy mieć pierwszy framework działający na Py 3k :) Czy to nie ekscytujące?

Saturday, January 22, 2011

Co w ostatnich tygodniach.

Dawno nie pisałem na blogu. Gdy jeszcze dzieliłem czas na studia i pracę starczało mi czasu na wszystko. Obecnie obcowaniem z komputerem staram się ograniczać do siedzenia przed nim w pracy, a wieczory i weekendy spędzać w inny sposób.

Ćwiczę Angielski. Umiałem go świetnie przed maturą, jednak studia inżynierskie skutecznie uwsteczniły mnie w tej materii. Jakiś już czas temu, bo w zeszłym roku, mój manager widząc braki, zorganizował spotkania z lektorką dzięki czemu wtorki i czwartki zaczynam lektoratem z języka angielskiego :) co skutecznie poprawia mi humor na pozostałą część tygodnia.

Co do języków programowania - wciąż używam Pytona, ze względu na jego znajomość zostałem zatrudniony i przez ostatnie 1,5 roku zostawiłem po sobie na tyle skryptów i aplikacji zapisanych w tym dialekcie, że ciężko codziennie się z nim nie stykać. Jednak moje marzenia i pasje kierują się w stronę Node.JS oraz wciąż zagadkowego dla mnie języka Scala.

Node.JS chciałem rozpocząć od przebrnięcia przez fantastyczny podręcznik do JavaScript "Eloquent JavaScript". Niestety, silnie funkcyjne podejście autora do sprawy skutecznie utrudnia mi przyswojenie lektury, a problemy zaczęły się już w rozdziale 4.

Co do Scala jest lepiej. Wiele zawdzięczam prelekcji Mikołaja Sochackiego Aplikacje webowe w Scala i Lift wygłoszonej na Zimowisku TLUGu. Sama prezentacja, jak i późniejsza wymiana doświadczeń w prywatnej rozmowie z prelegentem, pozwoliły mi dojść do wniosku, że trzeba przestać przejmować się, że "czegoś" nie rozumiem i opanować Scalę na miarę swoich możliwości - z czasem poznając ją może po prostu lepiej.

Tak też narodził się pomysł na prostego bloga, z przykładowymi aplikacjami w języku Scala, które skupiałyby się na konkretach i w prosty sposób pozwoliły na zapoznanie się z językiem. Co z tego wyjdzie - zobaczymy. Obecnie robię rozeznanie w silnikach, na których warto byłoby taki "blog" postawić. Z dotychczasowych poszukiwań wszystko wskazuje na Joggera - chyba, że znajdą się jakieś fundusze na zakup i utrzymanie domeny - wtedy będzie to Wordpress. Przy okazji trafiłem na Polski Portal Scala, na którym już w tej chwili można zapoznać się z niemałym zbiorem przykładów kodu w tym języku.

Jednak pierwszeństwo przed projektem Scalowym ma stworzenie Planety Pythona, którego podjąłem się niedawno w ramach mojej działalności w Polish Python Coders Group - wszak na koszulkę jakoś trzeba sobie zasłużyć :). Twarzą w twarz poznałem większość ekipy dopiero na PyCon.pl 2010 i co tu dużo gadać - są genialni. Kocham tych chłopaków za kawał dobrej roboty jaki odwalają, szczególnie na IRCu i Forum - uważam, że mamy fantastyczną scenę Pythonową w Polsce jakiej można tylko pozazdrościć i każdy kto chce zacząć przygodę z tym językiem nie mógłby sobie wymarzyć lepszej społeczności niż obecna.

Wracając do Zimowiska Linuksowego TLUG - było naprawdę fajnie. Dzięki zakwaterowaniu w Puckim HOMie czułem się jak na wczasach, do tego urok małego miasteczka jakim jest Puck - genialnie. Prelekcje były zróżnicowane, poziom wielu z nich naprawdę wysoki i profesjonalny. Szczególnie dało się to odczuć w prezentacjach Piotra Macuk, Tomasza Torcz (wiem, że gdzieś prowadzi bloga, ale nie mam adresu), Roberta Jaroszuk, Grzegorza Borowiak oraz Dariusza Puchalak. Subiektywnie jednak bardziej interesują mnie technologie webowe i ten charakter konferencji, która moim zdaniem była zaadresowana głównie do administratorów systemu Unix, nie przypadł mi specjalnie do gustu.

Co do spędzania czasu po pracy zagospodarowuję go w znacznej mierze treningami Aikido w Shoshin Dojo. I grubsza tyle z nowinek - wracam chorować :]

Sunday, November 7, 2010

Pyramid - następca Pylons

Kilka dni temu Kevin J. Smith napisał na grupie dyskusyjnej pylons-discuss, że jako użytkownik Pylons, czuje się troszkę zmieszany ponieważ pierwszy raz trafia na informacje o Pyramid.

Szybko okazało się, że developerzy Pylons zaczęli pracować już nad następcą Pylons - jednak nie ogłosili tego światu. Tak oto przypadkiem świat dowiedział się o Pyramid.

O kierunkach jakie przyjmie Pylons 2.0 można było przeczytać już kilka tygodni temu na blogu Bena Bangerta we wpisie Why Extending Through Subclassing (a framework’s classes) is a Bad Idea. Było to preludium do kierunku jakim podąży Pylons 2.0 - a właściwie powinienem powiedzieć Pyramid.

Pierwsze - Pyramid "połączyło się" z zespołem repoze.bfg. Połączyło się, a raczej stwierdziło, że dotychczasowy model tworzenia kolejny aplikacji (poprzez tworzenie podklas WSGIController) jest ślepym zaułkiem - przed czym zostali ostrzeżeni przez sławę CherryPy Boba Brewera. Aby nie wymyślać koła na nowo obecnie Pylons tworzony jako adaptacja repoze.bfg. Tak zostało wydane ogłoszenie iż obecnie repoze.bfg staje się projektem Pyramid i będzie wydawane pod tą nazwą. Dwa fantastyczne zespoły połaczyły siły aby na bazie już dobrze ukształtowanego repoze.bfg oraz posiadającego swoich fanów Pylons powstał jeszcze lepszy framework dla języka Python.

Dzięki temu połączeniu, oraz faktowi iż kod Pyramid posiada dobrze ugruntowaną bazę w postaci kodu repoze.bfg już dziś możemy cieszyć się Pyramid 1.0a dostępnym przez Python Package Index.

Te informacje napawają optymizmem. Wszystko wskazuje na to, że następca Pylons wyjdzie szybciej niż ktokolwiek by się spodziewał i będzie to naprawdę fantastyczny framework. Oby w parze z postępami w kodzie pojawiały się artykuły, a dokumentacja rosła :) Nic tylko czekać na Pyramid Book :)

Sunday, October 17, 2010

PyCons

Tydzień po powrocie z polskiego PyCona zacząłem oglądać konferencje z konferencji pythonowych, które odbyły się w innych częściach świata. Fantastyczną nowiną jest fakt iż większość z nich zamieszcza nagrania wideo prelekcji (nie tylko slajdy) więc można po prostu wysłuchać i zobaczyć prelekcję - taką jaka była - w zaciszu własnego domu.

Tematy poruszane w różnych zakątkach świata są bardzo różne :) i dobrze. Można się naprawdę wiele nauczyć i wybrać sobie te tematy, które odpowiednio pasują do naszego obecnego poziomu lub po prostu zainteresował nas temat. Tutaj pierwsza uwaga.

Temat konferencji czasami kompletnie nic nie mówi o jej treści. To smutne, ale widzisz temat i nie wiesz - warto to w ogóle odpalać, czy lepiej odpuścić sobie. Bo co na przykład mówi tytuł "Dude, Where's My Database?". Na szczęście są (przy większości tematów) opisy mówiące o treści konferencji. Bezcenne.

Druga rzecz - jakość materiałów. Chyba najlepiej zorganizowane są na stronie PyCon Atlanta. Naprawdę super. Łatwy dostęp do wszystkiego. Natomiast materiały wideo z UK czy Europy są tragiczne. Co z tego, że mają nagranie wideo skoro ani nie słychać na nim prowadzącego wykład ani nie widać wyraźnie slajdów. Po prostu ... bezużyteczne.

Osobiście czytanie dokumentacji ze zrozumieniem przychodzi mi z trudnością i nigdy nie mogę wyłapać w niej niuansów i szczegółów implementacyjnych. Takie prelekcje są dla mnie jak znalazł. Głównie dlatego, że ludzie w nich skupiają się na tym co jest ważne, dają przykłady i pokazują "big picture", który czasem ciężko samemu dostrzec. Te trzy aspekty sprawiają, że takie konferencje to dla mnie kopania wiedzy :) Polecam każdemu!

Monday, October 11, 2010

Jak kupiłem mIRCa

Tak. Wczoraj zakupiłem mIRCa. Zapłaciłem $24 - te $4 to podatek z Polski. Dlaczego?
Na IRCu wiele nie siedzę. Natomiast zamierzam trochę więcej niż wcześniej aby wesprzeć społeczność PPCG choćby odpowiadając na pytania początkujących.

To nie jest tak, że nigdy wcześniej nie używałem IRCa. Jak byłem chyba jeszcze w podstawówce to pamiętam moją siostrę, która siedziała na jakiś kanałach i opowiadała o jakiś ludziach, którzy też tam siedzą - totalny bezsens. IRC - narzędzie dla zakompleksionych, dla których jedyną drogą przetrwania stała się akceptacja przez wirtualną społeczność. Tak to wtedy postrzegałem.

Potem trafiłem na książkę "Dziennik Hakera" albo coś podobnego gdzie było napisane, że Hakerzy też używają IRCa. No tak - też odludki - to sobie siedzą. Potem była jakaś era wchodzenia na czaty Onetu i wszelkiej różne inne, zakładanie własnych czatów przez jakieś skrypty i tak jakoś to bez refleksyjnie obok mnie przeszło.

Dla mnie IRC stał się czymś wartościowym kiedy odkryłem freenode - czyli sieć gdzie są wartościowe kanały dotyczące języków programowania, w których koduję. Wejść na kanał, zapytać o coś, dowiedzieć się więcej, wziąć udział w jakiejś dyskusji. Wtedy IRC stał się dla mnie czymś użytecznym.

Dlaczego mIRC? Chłopaki z PPCG rzucali setkami pomysłów, ale żaden nie wpadł na pomysł aby kupić mIRCa. Jest to jedyny klient, który mi się podoba. Naprawdę. Wiem, że jest Quassel i IRSSI i dużo innych klientów, ale żaden darmowy mi nie podpasował. mIRC to jedyne co mi się naprawdę spodobało.

Mam nadzieję, że kupno mIRCa będzie inwestycją, nie wyrzuconymi pieniędzmi w błoto :] Zobaczymy - czas pokaże.

Wednesday, October 6, 2010

I mamy Gallery 3

W końcu, po wielu latach ciężkiego developmentu doczekaliśmy się Gallery 3. Skrypt w wersji drugiej był niesamowicie wolny i nie poddawał się w niemal żaden sposób żadnym zabiegom optymalizacyjnym. Mapowanie każdego pliku graficznego na skrypt PHP przez regułkę .htaccess w celu sprawdzenia uprawnień było najwęższym gardłem całego narzędzia.

Na ten dzień czekałem kilka miesięcy codziennie zaglądając na tracka projektu i badając ilość bugów pozostałych do releasu. W końcu nadszedł: nowa, bezpieczna, szybka, nowoczesna wersja jedynego w swoim rodzaju skryptu do obsługi galerii. Cieszy fakt, że jeden z twórców czerpał wiele inspiracji ze swojej fascynacji mistrzostwem z jakim został zaprojektowany Drupal. Tym bardziej jestem przekonany o jakości ostatecznego rozwiązania.

Pozostaje tylko się cieszyć i szykować na upgrade ZHRowej multigalerii :] Zachęcam wszystkich do pobrania :]

P.S. Skórek o dziwo nie brakuje :) jest już kilka do wyboru - niektóre naprawdę fajne :D

Saturday, October 2, 2010

Jednak Arch Linux

Po kilku latach powrót do Arch Linux to strzał w dziesiątkę. Szczególnie w moim przypadku gdy w gruncie rzeczy na co dzień używam Windows 7 a Linuksa tylko do webdevelopmentu.

Pierwszy plus - dużo grzebania. W Archu konfigurację z grubsza trzeba grzebnąć ręcznie - miła odmiana po "wszystko robiącym" Windows.

Po drugie - lekkość. SLiM i E17 po prostu.... miód na mojego biednego VirtualBox-a, który umierał pod jarzmem Ubuntu. Teraz rozwinął skrzydła.

Po trzecie - dokumentacja. Wszystko działa, krok po kroku opisane, właściwie nie miałem problemu ze znalezienim czegokolwiek. Opisane jest po prostu wszystko, w łatwym języku. Jakość instrkcji stuprocentowo wynagradza fakt iż często trzeba jakieś pliki systemowe zmienić manualnie.

Po czwarte - filozofia systemu. Taki sposób uczy Cię jak działa system a przez to rozwija.

Po piąte - model wydawniczy. Nowe wersje systemu to nic innego jak zwykły upgrade paczek pacman -Su raz na jakiś czas i nie muszę nic przeinstalowywać, pamiętać o oddzielnej partycji HOME, martwić się ustawieniami z HOMEDIR pochodzących z poprzedniej wersji systemu - nic. Niemal czysty bleeding edge w paczkach :)

Thursday, September 30, 2010

Ubuntu - to już dla mnie zbyt wiele

Moje używanie linuksa to najświeższe Ubuntu na beztrosko uruchomionym VirtualBox pod kontrolą radośnie działającego Windows 7 :) Dlaczego? Wygoda - nie muszę restartować komputera gdy zmieniam system, pełna kompatybilność sprzętowa - sprzęt nadal obsługuje Windows, który ma do niego dedykowane sterowniki nie zaś Linuks, który ich nie posiada i przez to nie mogłem np. wyłączyć głośników w Laptopie. Te dwa powody skłaniają mnie do korzystania z VirtualBox, ale co z dystrybucją?

Ubuntu zmienia się z roku na rok. Dzisiaj przeczytałem listę zmian Ubuntu 10.10 RC. Powiem krótko - nie interesuje mnie większość z nich. Oczywiście - nie uważam, że są złe. Moje użytkowanie Linuksa to ostatnio czysta deweloperka: Google Chrome, Vim, SSH, SCP, Ruby, Python, PHP - koniec. Najczęściej uruchamianym przeze mnie programem jest Terminal, w drugiej kolejności Google Chrome.

Wszystko co dla mnie jest fajne w nowej wersji systemu to nowe wersje programu. Wiem, że Canonical od dawna pracuje nad user-friendly systemu i dobrze im to wychodzi jednak dla mnie zmiany zachodzą w miejscach systemu, których w ogóle nie używam. Co rzutuje na moją pracę?
Chyba największą zmiana dla mnie jest nowa wersja oprogramowania, z mniejszą ilością bugów i nowymi featurami. Gdyby więc mieć tylko system, który cały ewoluuje na zasadzie apt-get update && apt-get upgrade to dla mnie to rozwiązanie byłoby idealne.

Minimalna dystrybucja - to był mój pierwszy pomysł. Debian w wersji base z doinstalowanymi paczkami, których wymagam. Z drugiej strony kiedyś już tak żyłem i Ubuntu okazało się o tyle lepsze, że gdy potrzebowałem czegoś "nagle" nieprzewidzianie to w Ubuntu już to miałem - w Debianie musiałem czekać aż się zainstaluje. Tak więc odchudzona wersja Ubuntu byłaby super. Na tyle obszerna aby miała już wiele rzeczy zainstalowanych, na tyle lekka aby nie przycinała VirtualBoxa. Jednak w międzyczasie wpadł mi do głowy inny pomysł - ChromeOS.

ChromeOS może okazać się "świętym gralem" dla osoby z moimi wymaganiami. Jest Google Chrome, jest konsola - cóż więcej mi trzeba? Oczywiście pod warunkiem, że będzie działał na VirtualBox - co się wkrótce okaże. Na pewno spróbuję tego systemu i przekonam się czy spełni moje oczekiwania. Do tego czasu pomyślę nad jakąś lżejszą dystrybucją Linuxa, która odciąży trochę moje zasoby VirtualBoxowe :)