itoutline.me

 

WSL - Ubuntu 18.04 - xfce4-terminal

Ubuntu 18.04 ma nowszą wersję xfce4-terminal 0.8.7.3 i jest w niej poprawiony pewien szczegół który mnie irytował, przypadkowe przechodzenie w tryb zaznaczania przy kliknięciu na okno xfce4. Bardzo łatwo było to zrobić i jeśli akurat miało się coś w schowku to trzeba było ponownie do niego kopiować. Teraz jest normalnie a na dodatek zaznaczenie blokowe w terminalu z wciśniętym Shift i Ctrl działa świetnie.

Została też poprawiona obsługa zmiennej TERM i COLORTERM, teraz sam xfce4 ustawia je bez konieczności dosyć złej praktyki modyfikowania ich w .bashrc itp.:

1
2
TERM=xterm-256color
COLORTERM=truecolor

Testowałem różne rozwiązania terminalowe na Windows - mintty, putty (via server ssh), Hyper, cmder), chyba tylko xfce4-terminal jest teraz bardzo bliski tego czego bym oczekiwał po terminalu (nawet mimo tego, że trzeba go uruchamiać przez Server X). Jest prawie tak dobry jak iTerm2 na OSX ;)

Dla odważnych sudo do-release-upgrade -d :)

Home Cloud

Kilka lat temu pozbyłem się z domu “blaszaka”. Nie gram, w związku z czym w miarę wydajny laptop miał mi spokojnie wystarczyć. No i w sumie tak było, brakowało mi tylko jednej rzeczy, jakiegoś wspólnego domowego zasobu sieciowego. Nie było to jakoś krytyczne, podejmowałem próby z BananaPi wyposażonym w port sata (bardzo słabo), podpinałem dysk do posiadanych routerów po USB3 (niewiele lepiej) a na dodatek ciągle miałem w głowie, że jeśli mi ten dysk padnie to tracę wszystko w związku z czym jakichś krytycznych rzeczy tam nie trzymałem.

W końcu zdecydowałem się jakoś docelowo rozwiązać problem i wybór padł na NAS Asus 6202T. Rozwiązanie sprawdzało się całkiem dobrze ale pojawiła się potrzeba “upchnięcia” trochę większej ilości wirtualnych maszyn, wersja Docker-a była nie tą, której potrzebowałem, brak wsparcia dla osobnych dysków SSD (w tamtym czasie) i jakieś inne drobne rzeczy skłoniły mnie do poszukania czegoś innego.

No i trafiłem na Unraid-a. Jest to dedykowany pod storage OS oparty na Linuxie. Podstawowe zalety w mojej ocenie:

  • Wsparcie dla wirtualizacji/dokeryzacji.
  • Obsługa SSD przez tzw. “cache pool”.
  • Bardzo łatwe dodawanie nowych docker-ów.
  • Niezależność od dostawcy sprzętu, to chyba największy plus, kupuje komponenty dokładnie take jakich potrzebuje. (Ludzie preferujący rozwiązania “półkowe” niekoniecznie uznają to za zaletę).
  • Możliwość “podpięcia” karty graficznej bezpośrednio do VM, dzięki czemu nie ma różnicy pomiędzy pracą na maszynie fizycznej a VM.
  • Całość ruchu sieciowego pomiędzy wszystkimi hostami odbywa się w obrębie jednej fizycznej maszyny:

  • Duża frajda z posiadania własnej chmury, Plex + NextCloud + Collabora + draw.io (Collabora - pakiet biurowy, może odstaje nieco jakością od rozwiązań gigantów ale już z draw.io korzysta mi się lepiej niż z Visio).
  • Wszytko jest na dyskach w RAID (co nie zwalnia z backup-ów ale zdecydowanie jest raźniej ;)

Wady:

  • Większe zużycie energii 50W, w przypadku Asus-a 10W (wartości mocno uśrednione). Coś za coś, I7 8700 vs Celeron
  • Rozwiązanie nie jest darmowe.
  • Nadal mam problem z podłączeniem zintegrowanej grafiki do VM Linuxowej (grubsza sprawa, musi dojść do przełączenia systemu obsługującego IGD z unRAID na VM).

Całość wygląda tak:

Historia zatoczyła koło, teraz potrzebuje byle jakiego laptopa i mogę pracować na VM zdalnie (w czym na pewno pomaga 50Mb upstream-u od dostawcy Internetu). Co najważniejsze, całość działa zaskakująco stabilnie. Niesamowite jak wiele funkcji może spełniać dzisiaj PC w domu (cztery ostatnie to VM) a wszystko to dzięki wirtualizacji i konteneryzacji.

Obciążenie CPU w tym czasie (żadna z maszyn nie robiła nic szczególnego, na Windows 10, Firefox z 20+ zakładkami i kilka pomniejszych programów):

Kiedyś bardzo optowałem za stawianiem drobnych rzeczy jak np. Home Assistant na RPI czy podobnych ale teraz wydaje mi się, że takie “pudło” jest zdecydowanie lepszym rozwiązaniem, ogarnia wszystko :)

The Cuttle - Boldport Club

Świetne projekty elektroniczne DIY - Boldport Club, zapisałem się i zacząłem od klona Arduino The Cuttle. Nie był to cały kit tylko sama płytka i trochę nieudana, bo od spodu jest miejscami farba na padach do lutowania. Mimo wszystko działa :)

W sumie pierwszy raz wgrywałem bootloader i tutaj bardzo pomocna okazała się stronka http://www.gammon.com.au/bootloader i sketch Atmega_Board_Programmer

Cały proces wyglądał tak:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Type 'C' when ready to continue with another chip ...
Attempting to enter ICSP programming mode ...
Entered programming mode OK.
Signature = 0x1E 0x95 0x14
Processor = ATmega328
Flash memory size = 32768 bytes.
LFuse = 0xFF
HFuse = 0xD9
EFuse = 0xFF
Lock byte = 0xFF
Clock calibration = 0xA9
Type 'L' to use Lilypad (8 MHz) loader, or 'U' for Uno (16 MHz) loader ...
Using Uno Optiboot 16 MHz loader.
Bootloader address = 0x7E00
Bootloader length = 512 bytes.
Type 'Q' to quit, 'V' to verify, or 'G' to program the chip with the bootloader ...
Erasing chip ...
Writing bootloader ...
Committing page starting at 0x7E00
Committing page starting at 0x7E80
Committing page starting at 0x7F00
Committing page starting at 0x7F80
Written.
Verifying ...
No errors found.
Writing fuses ...
LFuse = 0xFF
HFuse = 0xDE
EFuse = 0xFD
Lock byte = 0xEF
Clock calibration = 0xA9
Done.
Programming mode off.

Picocom na Cygwin/Windows10

Działa i instalacja poszła wyjątkowo łatwo:

1
git clone https://github.com/npat-efault/picocom; cd picocom && make
1
2
3
4
5
6
7
8
9
10
11
12
Cloning into 'picocom'...
remote: Counting objects: 701, done.
remote: Total 701 (delta 0), reused 0 (delta 0), pack-reused 701
Receiving objects: 100% (701/701), 490.39 KiB | 493.00 KiB/s, done.
Resolving deltas: 100% (445/445), done.
cc -Wall -g -DVERSION_STR=\"2.3a\" -DTTY_Q_SZ=32768 -DHIGH_BAUD -DUSE_FLOCK -DHISTFILE=\".picocom_history\" -DLINENOISE -o linenoise-1.0/linenoise.o -c linenoise-1.0/linenoise.c
cc -Wall -g -DVERSION_STR=\"2.3a\" -DTTY_Q_SZ=32768 -DHIGH_BAUD -DUSE_FLOCK -DHISTFILE=\".picocom_history\" -DLINENOISE -o picocom.o -c picocom.c
cc -Wall -g -DVERSION_STR=\"2.3a\" -DTTY_Q_SZ=32768 -DHIGH_BAUD -DUSE_FLOCK -DHISTFILE=\".picocom_history\" -DLINENOISE -o term.o -c term.c
cc -Wall -g -DVERSION_STR=\"2.3a\" -DTTY_Q_SZ=32768 -DHIGH_BAUD -DUSE_FLOCK -DHISTFILE=\".picocom_history\" -DLINENOISE -o fdio.o -c fdio.c
cc -Wall -g -DVERSION_STR=\"2.3a\" -DTTY_Q_SZ=32768 -DHIGH_BAUD -DUSE_FLOCK -DHISTFILE=\".picocom_history\" -DLINENOISE -o split.o -c split.c
cc -Wall -g -DVERSION_STR=\"2.3a\" -DTTY_Q_SZ=32768 -DHIGH_BAUD -DUSE_FLOCK -DHISTFILE=\".picocom_history\" -DLINENOISE -o termios2.o -c termios2.c
cc -g -o picocom  linenoise-1.0/linenoise.o picocom.o term.o fdio.o split.o termios2.o

Gdyby nie było make to apt-cyg install make.

Trzeba tylko pamiętać, że np. COM4 to /dev/ttyS3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ ./picocom.exe -b 115200 /dev/ttyS3
picocom v2.3a

port is        : /dev/ttyS3
flowcontrol    : none
baudrate is    : 115200
parity is      : none
databits are   : 8
stopbits are   : 1
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv -E
imap is        :
omap is        :
emap is        : crcrlf,delbs,
logfile is     : none

Type [C-a] [C-h] to see available commands

Terminal ready

HiZ>
HiZ>

Iptables i dynamiczne IP

W przypadku posiadania serwera w sieci Internet zawsze najlepiej jest ograniczać do niego dostęp tylko do tego co rzeczywiście chcemy, żeby było na nim dostępne. Dodatkowo ograniczenie do konkretnych klas czy adresów w przypadku dostępu do interfejsów umożliwiających większą kontrolę nad serwerem jest także dobrą praktyką (jeszcze lepszą jest nie eksponowanie ich w Internecie w ogóle;)

Ostatnio prowadziłem testy na takim serwerze i naturalnym było np. ograniczenie dostępu do SSH dla konkretnych adresów. Problem polega na tym, że o ile w firmie miałem statyczny adres to w domu już nie. Mogłem ustawić regułę na obecny domowy adres ale za kilka godzin mogła być już nieaktualna. Wyjściem z sytuacji okazał się, jak bardzo często się zdarza, prosty skrypt i dyndns.

iptables_update.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash
# --==itoutline.me==--

HOSTALLOWED="/home/itoutline/update_iptables/allowed_host.txt"

while read line
do

  HOSTNAME=$line
  LOGFILE=/home/itoutline/update_iptables/"$line".log

  Current_IP=$(host $HOSTNAME | cut -f4 -d' ')

  if [ $LOGFILE == "" ] ; then
    iptables -I INPUT -s $Current_IP -j ACCEPT
    echo $Current_IP > $LOGFILE
  else

    Old_IP=$(cat $LOGFILE)

    if [ "$Current_IP" != "$Old_IP" ] ; then
      iptables -D INPUT -s $Old_IP -j ACCEPT
      iptables -I INPUT -s $Current_IP -j ACCEPT
      /etc/init.d/iptables save
      echo $Current_IP > $LOGFILE
      echo iptables have been updated
    fi
  fi
done < "$HOSTALLOWED"

W allowed_host.txt umieszczamy w kolejnych liniach nazwy domenowe hostów.

A do cron-a dodajemy linijkę:

iptables_update.sh
1
*/1 * * * * /home/itoutline/update_iptables/update_iptables.sh  2>&1 |logger

Unblock.us automatyczna aktualizacja

Wchodzenie na stronę unblock.us i aktualizowanie bieżącego adresu IP zaczęło mnie naprawdę męczyć. Na szczęście można tego uniknąć dosyć prosto. Wystarczy prosty skrypt na routerze (czy dowolnym serwerze linuxowym jaki mamy w domu, chyba każdy ma coś na poziomie minimum rpi w dzisiejszych czasach ;), który będzie sprawdzał co jakiś czas adres zewnętrzny i aktualizował go w unblock.us.

update_unblock.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/env bash
# --==itoutline.me==--

SCRIPT_NAME="$(basename $0)"
IP_ADDR=/tmp/active_ip_addr
IP_STATUS=/tmp/ip_update_status

CURRENT_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)

function update_ip {
    curl -s -o $IP_STATUS "https://api.unblock-us.com/login?adres_email:hasło"
    logger "[$SCRIPT_NAME]: IP updated: $CURRENT_IP; Response: $(cat $IP_STATUS)"
    echo $CURRENT_IP > $IP_ADDR
}

if [[ "$CURRENT_IP" =~ ^[0-9]{2,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] ; then
    if [ ! -f $IP_ADDR ] ; then
        update_ip
    else
        OLD_IP=$(cat $IP_ADDR)
        if [[ "$CURRENT_IP" != "$OLD_IP" ]] ; then
            update_ip
        fi
    fi
else
    logger "[$SCRIPT_NAME]: Network error or incorrect answer from the IP provider"
fi

W miejscach adres_email i hasło trzeba podać swoje dane oraz dorzucić skrypt do crona.

*/2 * * * * /root/update_unblock.sh  2>&1 |logger

Skrypt będzie się wykonywał co dwie minuty.

Skrypt można również wykorzystać do innych serwisów, w przypadku darmowego tvunblock.com polecenie curl z funkcji update_ip należałoby zastąpić:

curl -s -o $IP_STATUS "https://activate.tvunblock.com/"

Zastąpienie odpytywania zewnętrznego serwisu o publiczny adres IP

Serwisów dostarczających za pomocą jakiegoś web api zewnętrzny adres ip jest dużo ale nie zawsze trzeba z nich korzystać. Jeśli router/modem pozwala na pobieranie z niego informacji o adresie WAN, dlaczego tego nie użyć? W przypadku Liveboxa/Funboxa zmienną CURRENT_IP można ustawić w ten sposób:

CURRENT_IP=$(curl -silent -A "application/x-sah-ws-4-call+json" "http://192.168.1.1/sysbus/NMC:getWANStatus" -d"{\"parameters\":{}}" | sed -n -e 's/^.*\(IPAddress":"\)\([0-9]*.[0-9]*.[0-9]*.[0-9]*\)\(.*\)$/\2/p')

W praktyce (jak widać nie tylko adres ip portu WAN można podejrzeć):

Crontab tuning

Rozwiązania, które opierają się na crontabie i czesto są uruchamiane zaśmiecają sysloga:

Nov  8 16:49:01 bananapi /USR/SBIN/CRON[27209]: (root) CMD (/root/update_unblock.sh  2>&1 |logger)
Nov  8 16:51:01 bananapi /USR/SBIN/CRON[27221]: (root) CMD (/root/update_unblock.sh  2>&1 |logger)
Nov  8 16:53:01 bananapi /USR/SBIN/CRON[27233]: (root) CMD (/root/update_unblock.sh  2>&1 |logger)
Nov  8 16:55:01 bananapi /USR/SBIN/CRON[27244]: (root) CMD (/root/update_unblock.sh  2>&1 |logger)
Nov  8 16:57:01 bananapi /USR/SBIN/CRON[27255]: (root) CMD (/root/update_unblock.sh  2>&1 |logger)
Nov  8 16:59:01 bananapi /USR/SBIN/CRON[27266]: (root) CMD (/root/update_unblock.sh  2>&1 |logger)

Dlatego kiedy już wiadomo, że skrypt działa poprawnie można pokusić się o wyłączenie logowania crona. Na Debianie to modyfikacja pliku /etc/rsyslog.conf:

rsyslog.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
###############
#### RULES ####
###############

#
# First some standard log files.  Log by facility.
#
auth,authpriv.*         -/var/log/auth.log
*.*;auth,authpriv.none,cron.none        -/var/log/syslog
#cron.*             -/var/log/cron.log
daemon.*            -/var/log/daemon.log
kern.*              -/var/log/kern.log
lpr.*               -/var/log/lpr.log
mail.*              -/var/log/mail.log
user.*              -/var/log/user.log

Dorzucenie cron.none i restart usługi sudo /etc/init.d/rsyslog restart wyciszy crontaba. Można również przekierować logi do osobnego pliku cron.log ale szkoda karty SD. Od tej pory syslog nie jest floodowany z powodu skryptu i mamy tylko informacje kiedy faktcznie skrypt wykona jakąś pracę:

Nov  8 20:16:02 bananapi logger: [update_unblock.sh]: IP updated: 178.42.100.100; Response: active

Zmienne systemowe w OSX

Definiowanie zmiennych systemowych w OSX jest takie sobie… Nie mówię tutaj o zmiennych, które można ustawić w plikach inicjalizacyjnych powłoki shellowej (bash, zsh, fish czy co komu odpowiada). Tam akurat wszystko jest całkiem prosto ale o ustawieniu zmiennej bez uruchamiania terminala po starcie systemu. Natrafiłem na potrzebę zdefiniowania takiej zmiennej przy zabawie z Android Studio. Po zainstalowaniu Javy i wspomnianego oprogramowania, próba jego uruchomienia kończyła się tak:

Problemem okazał się brak zmiennej STUDIO_JDK. Można ten problem obejść np. tak:

launchctl setenv STUDIO_JDK /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk
open /Applications/Android\ Studio.app

Tylko, że jakoś konieczność uruchomienia terminala po to, żeby pracować w aplikacji graficznej do mnie nie przemawia. Udało mi się znaleźć ciekawe rozwiązanie problemu tutaj.

Zmienne systemowe

Zmienne mogą być ustawione na poziomie użytkownika (ustawienie wywoływane przez /Library/LaunchAgents/environment.user.plist) lub root-a (/Library/LaunchDaemons/environment.plist). Rozwiązanie zakłada jeden plik w którym będą definiowane zmienne /etc/environment, co jest bardzo ok bo nie przypominam sobie, żebym kiedyś potrzebował różnych. Kolejnym plusem jest fakt, że modyfikacja /etc/environment czyli dodanie jakiejś zmiennej automatycznie jest zaczytywane i dostajemy wzrokową informację w postaci chwilowego zniknięcia Dock-a.

Jedyny minus ale to jest raczej nie do obejścia to fakt, że już działająca aplikacja nie pobierze informacji o nowej zmiennej, musi być ponownie otworzona.

Zmienna PATH

To rozwiązanie jest jeszcze lepsze i dopóki będzie działało na OSX to będę z niego korzystał a mianowicie zmiany dokonujemy w pliku /etc/paths. To zwykły plik tekstowy w którym możemy dodawać kolejne linijki z wymaganymi przez nas ścieżkami. Po ponownym uruchomieniu terminala dopisana przez nas ścieżka znajdzie się w zmiennej PATH.

Ostatecznie

Przygotowałem skrypt bashowy, który tworze niezbędne pliki i ustawia ich parametry.

(set_env_var.sh) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/env bash

sudo -v

cat << EOF | sudo tee /etc/environment > /dev/null
#!/bin/sh

set -e

syslog -s -l warn "Set environment variables with /etc/environment $(whoami) - start"


### Set your variable here:
#launchctl setenv JAVA_HOME      /usr/local/jdk1.7
launchctl setenv MAVEN_HOME     /opt/local/share/java/maven3
launchctl setenv STUDIO_JDK     /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk
############################

if [ -x /usr/libexec/path_helper ]; then
        export PATH=""
            eval `/usr/libexec/path_helper -s`
                launchctl setenv PATH $PATH
            fi

            osascript -e 'tell app "Dock" to quit'

            syslog -s -l warn "Set environment variables with /etc/environment $(whoami) - complete"
EOF

cat << EOF | sudo tee /Library/LaunchAgents/environment.user.plist > /dev/null
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>environment.user</string>
    <key>ProgramArguments</key>
    <array>
            <string>/etc/environment</string>
    </array>
    <key>KeepAlive</key>
    <false/>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment</string>
    </array>
</dict>
</plist>
EOF

cat << EOF | sudo tee /Library/LaunchDaemons/environment.plist > /dev/null
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>environment</string>
    <key>ProgramArguments</key>
    <array>
            <string>/etc/environment</string>
    </array>
    <key>KeepAlive</key>
    <false/>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment</string>
    </array>
</dict>
</plist>
EOF

sudo chmod 555 /etc/environment
sudo chmod 600 /Library/LaunchAgents/environment.user.plist /Library/LaunchDaemons/environment.plist
sudo chown root:wheel /etc/environment /Library/LaunchAgents/environment.user.plist /Library/LaunchDaemons/environment.plist

launchctl load -w /Library/LaunchAgents/environment.user.plist
sudo launchctl load -w /Library/LaunchDaemons/environment.plist

Zastosowanie rozwiązania:

wget http://itoutline.me/code/set_env_var.sh
chmod +x set_env_var.sh
./set_env_var.sh

Od tej pory zdefiniowanie jakiejkolwiek zmiennej, która będzie zawsze i wszędzie widoczna to umieszczenie jej w /etc/environment.

Pożyteczne komendy

Ustawienie zmiennej z poziomu terminala (będzie od razu widoczne w systemie ale na liście zmiennych wyświetlanej np. za pomocą env czy echo $STUDIO_JDK pojawi się dopiero po restarcie terminala:

launchctl setenv STUDIO_JDK /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk

Sprawdzenie zmiennej w systemie:

launchctl getenv STUDIO_JDK /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk

Sprawdzenie czy zmienna jest już widoczna w sesji terminala:

echo $STUDIO_JDK

Wyświetlenie wszystkich zmiennych widocznych z poziomu terminala:

env

Ustawienie zmiennej tylko na poziomie terminala:

export STUDIO_JDK=/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk

Chrome i swipe

W końcu wróciłem na stare śmieci, działam na OSX Yosemite. Przyznam, że zaskakują mnie oceny tej wersji OSX na AppStore ponieważ póki co jedyny kłopot jakiego ja doświadczyłem to ten z tytułu wpisu. Ponad tydzień spędzony na konfigurowaniu, instalowaniu, modyfikowaniu nie przyniósł jakichś większych zgrzytów, no ale pożyjemy zobaczymy. Zdecydowanie za wcześnie na wyciąganie wniosków.

Na pewno beznadziejnie działa przewijanie za pomocą dwóch palców w Chromie, bardzo często zdarzało mi się podczas przewijania strony w górę/dół lądować na poprzednio przeglądanej. Wydaje mi się, że to bardziej wina przeglądarki niż systemu…

Rozwiązanie problemu to wyłączenie przewijania w Chromie:

defaults write com.google.Chrome AppleEnableSwipeNavigateWithScrolls -bool false

Jeśli chcemy można w konfiguracji Touchpad-a zastosować poniższe ustawienia, dzięki czemu przechodzenie pomiędzy stronami przestanie być losowe. Jedyny minus to, że musimy użyć trzech palców.

Babun

Tak się nieszczęśliwie poukładało w moim życiu, że na jakiś czas wylądowałem z windowsowym laptopem. Zawsze kiedy musiałem korzystać z systemu MS instalowałem od razu Cygwina. Niestety czasami nie była to “bułka z masłem”, często coś tam nie do końca działało albo były problemy z samą instalacją. Zdarzało się, że trochę pracy było potrzebne ale i tak świetnie, że komuś się chciało i Cygwin w ogóle powstał. Teraz jest jeszcze lepiej bo powstało coś dającego Cygwina w bardzo fajnym opakowaniu. Mowa o Babun.

Instalacja

Sprowadza się do pobrania archiwum, rozpakowania i uruchomieniu skryptu. Standardowo instaluje się w katalogu domowym jako .babun.

Pierwsze wrażenia

Na pulpicie tworzy się skrót, który uruchamia terminal mintty a tam od razu mamy skonfigurowane zsh i jest git. Instalacja/deinstalacja pakietów za pomocą pact install oraz pact remove jest dużym plusem. Usunięcie Babun-a to skasowania jego katalogu, uwielbiam tego typu programy :)

Serwer SSH

Serwer SSH na Windowsie to chyba nigdy nie było proste. Tutaj też nie działa bez drobnych modyfikacji ale nie jest najgorzej. No i trzeba przyznać, że w Windows 8.1 dodawanie i usuwanie serwisów nawet z poziomu Babuna/Cygwina nie wymaga restartu. Miłe zaskoczenie.

Zaczynamy od uruchomienia Babuna jako Administrator i wydajemy następujące komendy:

/usr/bin/chmod +r /etc/passwd
/usr/bin/chmod +r /etc/group
/usr/bin/chmod +x /var
/usr/bin/ssh-host-config

Proces instalacji wyglądał u mnie tak:

ssh-keygen: generating new host keys: RSA1 RSA DSA ECDSA ED25519
*** Info: Creating default /etc/ssh_config file
*** Info: Creating default /etc/sshd_config file
*** Info: Privilege separation is set to yes by default since OpenSSH 3.3.
*** Info: However, this requires a non-privileged account called 'sshd'.
*** Info: For more info on privilege separation read /usr/share/doc/openssh/README.privsep.
*** Query: Should privilege separation be used? (yes/no) yes
*** Info: Note that creating a new user requires that the current account have
*** Info: Administrator privileges.  Should this script attempt to create a
*** Query: new local account 'sshd'? (yes/no) yes
*** Info: Updating /etc/sshd_config file

*** Query: Do you want to install sshd as a service?
*** Query: (Say "no" if it is already installed as a service) (yes/no) yes
*** Query: Enter the value of CYGWIN for the daemon: [] ntsec
*** Info: On Windows Server 2003, Windows Vista, and above, the
*** Info: SYSTEM account cannot setuid to other users -- a capability
*** Info: sshd requires.  You need to have or to create a privileged
*** Info: account.  This script will help you do so.

*** Info: You appear to be running Windows XP 64bit, Windows 2003 Server,
*** Info: or later.  On these systems, it's not possible to use the LocalSystem
*** Info: account for services that can change the user id without an
*** Info: explicit password (such as passwordless logins [e.g. public key
*** Info: authentication] via sshd).

*** Info: If you want to enable that functionality, it's required to create
*** Info: a new account with special privileges (unless a similar account
*** Info: already exists). This account is then used to run these special
*** Info: servers.

*** Info: Note that creating a new user requires that the current account
*** Info: have Administrator privileges itself.

*** Info: No privileged account could be found.

*** Info: This script plans to use 'cyg_server'.
*** Info: 'cyg_server' will only be used by registered services.
*** Query: Do you want to use a different name? (yes/no) no
*** Query: Create new privileged user account 'cyg_server'? (yes/no) yes
*** Info: Please enter a password for new user cyg_server.  Please be sure
*** Info: that this password matches the password rules given on your system.
*** Info: Entering no password will exit the configuration.
*** Query: Please enter the password:
*** Query: Reenter:

*** Info: User 'cyg_server' has been created with password 'dynamic1'.
*** Info: If you change the password, please remember also to change the
*** Info: password for the installed services which use (or will soon use)
*** Info: the 'cyg_server' account.

*** Info: Also keep in mind that the user 'cyg_server' needs read permissions
*** Info: on all users' relevant files for the services running as 'cyg_server'.
*** Info: In particular, for the sshd server all users' .ssh/authorized_keys
*** Info: files must have appropriate permissions to allow public key
*** Info: authentication. (Re-)running ssh-user-config for each user will set
*** Info: these permissions correctly. [Similar restrictions apply, for
*** Info: instance, for .rhosts files if the rshd server is running, etc].


*** Info: The sshd service has been installed under the 'cyg_server'
*** Info: account.  To start the service now, call `net start sshd' or
*** Info: `cygrunsrv -S sshd'.  Otherwise, it will start automatically
*** Info: after the next reboot.

*** Info: Host configuration finished. Have fun!

Ustawienie odpowiednich uprawnień:

/usr/bin/chmod 600 /etc/ssh*
/usr/bin/chown cyg_server /etc/ssh*
/usr/bin/chmod 600 /var/empty

Uruchominie serwera SSH /usr/bin/cygrunsrv -S sshd i oto jesteśmy:

Gdyby coś poszło nie tak można usunąć konfigurację, potem katalog Babuna i spróbować jeszcze raz.

cygrunsrv --remove sshd
net user sshd /delete
net user cyg_server /delete
rm /etc/ssh_host* /etc/sshd_config

Python, virtualenv i np. Tornado

W Babunie mamy zainstalowanego pythona w wersji 2.7.3. Instalacja pip-a i serwera Tornado przeszła bez żadnych kłopotów. Pip:

wget https://raw.githubusercontent.com/pypa/pip/master/contrib/get-pip.py
python get-pip.py

Virtualenv:

pip install virtualenv

Tornado:

mkdir tornado-test
cd tornado-test
virtualenv venv
source venv/bin/activate
pip install tornado

Kod serwera ;)

server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello from Babun")

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

Uruchomienie python server.py:

Ruby… i Octopress

Zdecydowanie najwięcej kłopotów, ale to nie jest jakoś bardzo dziwne. Niemniej jednak udało mi sie uruchomić Octopress-aa, było to tak:

Instalacja rbenv i ruby-build, zdecydowałem się nie korzystać z wersji oferowanej przez “pact”.

git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(rbenv init -)"' >> ~/.zshrc
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

Aktywacja rbenv:

source ~/.zshrc

Instalacja wersji 1.9.3-p551 i ustawienie jej jako domyślnej.

rbenv install 1.9.3-p551
rbenv global 1.9.3-p551

Tutaj zaczynają się schody, zaczynamy od stworzenia pliku z bibliotekami jakie zainstalowały się z ruby.

find /home/$USER/.rbenv -iname '*.so' > /tmp/ruby.gems.local.so.lst

Zamykamy wszystkie sesje babuna i uruchamiamy dash.exe z katalogu .babun\cygwin\bin, tam wydajemy polecenie:

/usr/bin/rebaseall -v -T /tmp/ruby.gems.local.so.lst

Bez “rebaseall” podczas instalacji wymaganych bibliotek przez Octopress-a miałem takie problemy:

{ octopress } master » bundle install                                                
Fetching gem metadata from https://rubygems.org/........
Resolving dependencies...
      0 [main] ruby 3412 child_info_fork::abort: address space needed by 'fcntl.so' (0x5F0000) is already occupied
      1 [main] ruby 2692 child_info_fork::abort: address space needed by 'fcntl.so' (0x5F0000) is already occupied
      0 [main] ruby 10092 child_info_fork::abort: address space needed by 'fcntl.so' (0x5F0000) is already occupied
      0 [main] ruby 3188 child_info_fork::abort: address space needed by 'fcntl.so' (0x5F0000) is already occupied

Instalacja Octopress-a:

git clone git://github.com/imathis/octopress.git octopress
cd octopress
gem install bundler
rbenv rehash
bundle install

Po “rebaseall” wygląda to lepiej:

{ octopress } master » bundle install                                                
Fetching gem metadata from https://rubygems.org/........
Resolving dependencies...
Installing rake 10.4.2
Installing RedCloth 4.2.9
Installing blankslate 2.1.2.4
Installing hitimes 1.2.2
Installing timers 4.0.1
Installing celluloid 0.16.0
...

Kolejny krok to zmiana w pliku Rakefile z:

1
2
3
4
if (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
  puts '## Set the codepage to 65001 for Windows machines'
  `chcp 65001`
end

na:

1
2
3
4
if (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
  puts '## Set the codepage to 65001 for Windows machines'
  `chcp.com 65001`
end

Bez powyższego kroku miałem taki problem:

{ octopress } master » rake install                                                   
rake aborted!
Errno::ENOENT: No such file or directory - chcp 65001
/home/itoutline/octopress/Rakefile:32:in ``'
/home/itoutline/octopress/Rakefile:32:in `<top (required)>'
(See full trace by running task with --trace)

Wykonujemy rake install:

{ octopress } master » rake install                                                   
## Set the codepage to 65001 for Windows machines
## Copying classic theme into ./source and ./sass
mkdir -p source
cp -r .themes/classic/source/. source
mkdir -p sass
cp -r .themes/classic/sass/. sass
mkdir -p source/_posts
mkdir -p public

Następnie rake generate && rake preview:

{ octopress } master » rake generate && rake preview                                  
## Set the codepage to 65001 for Windows machines
## Generating Site with Jekyll
directory source/stylesheets
    write source/stylesheets/screen.css
Configuration file: /home/itoutline/octopress/_config.yml
            Source: source
       Destination: public
      Generating...
                    done.
 Auto-regeneration: disabled. Use --watch to enable.
## Set the codepage to 65001 for Windows machines
Starting to watch source with Jekyll and Compass. Starting Rack on port 4000
[2014-12-29 15:22:08] INFO  WEBrick 1.3.1
[2014-12-29 15:22:08] INFO  ruby 1.9.3 (2014-11-13) [i386-cygwin]
[2014-12-29 15:22:08] WARN  TCPServer Error: Bad file descriptor - listen(2)
[2014-12-29 15:22:08] INFO  WEBrick::HTTPServer#start: pid=4924 port=4000
>>> Compass is watching for changes. Press Ctrl-C to Stop.
Configuration file: /home/itoutline/octopress/_config.yml
    write public/stylesheets/screen.css
            Source: source
       Destination: public
      Generating...
                    done.

Mamy bloga:

Ale to nie wszystko, próba umieszczenia takiego wpisu:

na blogu, zakończy się tak:

{ octopress } master » rake generate && rake preview                                  
## Set the codepage to 65001 for Windows machines
## Generating Site with Jekyll
    write source/stylesheets/screen.css
Configuration file: /home/itoutline/octopress/_config.yml
            Source: source
       Destination: public
      Generating...
  Liquid Exception: No such file or directory - C:\Windows\system32\cmd.exe in _posts/2014-12-29-nowy-post.markdown/#excerpt
                    done.
 Auto-regeneration: disabled. Use --watch to enable.
## Set the codepage to 65001 for Windows machines
Starting to watch source with Jekyll and Compass. Starting Rack on port 4000
[2014-12-29 15:35:49] INFO  WEBrick 1.3.1
[2014-12-29 15:35:49] INFO  ruby 1.9.3 (2014-11-13) [i386-cygwin]
[2014-12-29 15:35:49] WARN  TCPServer Error: Bad file descriptor - listen(2)
[2014-12-29 15:35:49] INFO  WEBrick::HTTPServer#start: pid=7540 port=4000

Rozwiązaniem jest ustawienie COMSPEC:

export COMSPEC=/cygdrive/c/Windows/System32/cmd.exe

najlepiej od razu dodać do ~/.zshrc:

echo "export COMSPEC=/cygdrive/c/Windows/System32/cmd.exe" >> ~/.zshrc

Ostatni drobny kłopot to narzekanie na brak “python2” podczas generowania bloga:

which: no python2 in (/home/itoutline/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/bin:/home/itoutline/.rbenv/versions/1.9.3-p551/bin:/home/itoutline/.rbenv/libexec:/home/itoutline/.rbenv/plugins/ruby-build/bin:/home/itoutline/.rbenv/shims:/home/itoutline/.rbenv/bin:/home/itoutline/bin:/usr/local/bin:/usr/bin:/cygdrive/c/ProgramData/Oracle/Java/javap~...

Wystarczy utworzenie linku symbolicznego:

cd /usr/bin
ln -s python2.7.exe python2

“Chyba” wszystko działa:

Przed podsumowaniem

Czasami po uruchomieniu Babun-a może się pojawić coś takiego:

compdef: unknown command or service: git
compdef: unknown command or service: git
compdef: unknown command or service: git
compdef: unknown command or service: git
compdef: unknown command or service: git
compdef: unknown command or service: git
compdef: unknown command or service: git
{ ~ }  »

Nie jest tak, że to tylko u mnie. Rozwiązanie w postaci:

compinit
cp .zcompdump .zcompdump-$HOSTNAME-5.0.2

rzeczywiście działa.

Podsumowując

Fajnie, że jest Cygwin, że powstał Babun ale chyba zdecydowanie lepiej jest po prostu uruchomić wirtualną maszynę na Virtualboxie. Chyba, że mamy ograniczone zasoby sprzętowe, nie mamy uprawnień, lubimy “grzebać” albo potrzebujemy dostępu tylko do podstawowych narzędzi Linux/GNU. Jeśli chodzi o to ostatnie to Cygwin/Babun zdecydowanie wygrywa z wirtualną maszyną.