poniedziałek, 25 stycznia 2021

Trzy kroki przed orkiestrą, czyli stary AfterShotPro(3) na nowej Fedorze(33)

    Trochę fotografuję, a że dość kiepsko, to muszę potem moje "dzieła" poprawiać. Tu doświetlić, tam kolor podkręcić, gdzieś coś z cienia wyciągnąć czy wykadrować jakiegoś przeoczonego "mistrza drugiego planu". Dość, by robić zdjęcia w surowym formacie NEF (RAWy z mojego ukochanego Nikona). Jestem też linuxowym talibem. Jeśli wychodzi nowe wydania Fedory, to zwykle je instaluję jeszcze tego samego dnia kiedy wyjdą. Pozwala mi to cieszyć się najnowszymi "ficzurami" ulubionej dystrybucji, ale dostarcza też sporo niespodzianek i rozrywki, zwłaszcza z zamkniętym oprogramowaniem, które często nie nadąża za open source. I tu dochodzimy do sedna: od dawna jestem (coraz mniej szczęśliwym) posiadaczem licencji komercyjnego, i oczywiście zamkniętego Corel AfterShotPro. Przesiadki na otwartego Darktable jakoś mi nie wyszły.

    Corel AfterShot Pro 3 to fajny, intuicyjny i ultraszybki  program do obróbki zdjęć w formacie RAW.  Dostawca niestety traktuje wersję linuxową jak drogowcy zimą drogę w mojej wsi: nie odświeżył wersji już od dwóch lat. A Fedora w międzyczasie poszła ostro do przodu. Jak wiadomo, ta dystrybucja potrafi zrobić grube zmiany w ABI pomiędzy wydaniami. W efekcie AfterShoot przestał działać już na wersji F32, nie wspominając o bieżącej F33. Oczywiście od czego KVM/VirtualBox/VMware? Ale po co utrzymywać CAŁĄ, około 30 GiB maszynę, żeby trzymać software wielkości 70MiB?  Dlatego zdecydowałem się na kontenery. 

    Mówiąc w skrócie, mój pomysł jest rozwinięciem koncepcji przedstawionej tutaj, i sprowadza się do:

  • Stworzenia definicji obrazu kontenera.
  • Zbudowania go
  • Uruchomienia programu
  • Posprzątania po zatrzymanym kontenerze. 

Dockerfile

    Natywnym dla Fedory (czyt. przyszłych Red Hatów) systemem obsługi kontenerów jest podman. Jest fajny, bo:

  • jest daemonless - nie ma żadnego demona do obsługi kontenerów.
  • domyślnie działa z konta zwykłego użyszkodnika a nie roota  - przy klasycznym Dockerze trzeba to trochę pokofigurować.
  • Jest kompatybilny z Dokckerem więc przesiadka jest bezbolesna.

Trochę metodą prób i błędów, trochę przy pomocy zaprzyjaźnionego inkwizytora Dockerowo/Kubernetesowo/OpenShiftowego (Michał Stryga) doszedłem do takiego Dockerfile:


FROM fedora:31

ADD AfterShotPro3.rpm /AfterShotPro3.rpm

ADD start.sh /start.sh

RUN dnf -y install AfterShotPro3.rpm glx-utils xterm mesa-dri-drivers compat-openssl10 xorg-x11-fonts-Type1 xorg-x11-fonts-ISO8859-1-100dpi dejavu-sans-fonts dejavu-serif-fonts liberation-serif-fonts 

CMD ["/start.sh"]


    Jak widać, niezwykle prosty:

  1. Korzysta z bazowej Fedory w wersji 31 - Wiem, wiem, niewspierana, ale właśnie ta musi być, bo to ostatnia na jakiej AfterShot 3 (A konkretnie 3.6.0.380) działa.
  2. Dodaje do obrazu pakiet ze wspomnianym AfterShotem oraz skryptem startującym. - sekcje ADD.
  3. Instaluje potrzebne pakiety. Teoretycznie sam AfterShot definiuje swoje zależności, więc dnf'owi powinien wystarczyć tylko ten pakiet, ale jak to w komercyjnych softach bywa, definiuje je niedbale. Stąd, metodą prób i błędów, okresliłem listę pakietów, które są mu potrzebne do szczęścia.
  4. Jako "Entry Point" definiuje skrypt start.sh, którego zadaniem jest "zaczarowanie" OpenGL i GLXa. Znowu, metodą prób i błędów, okazało się, że binarka AfterShota nie startuje, jeśli ktoś przed nią nie wykona czegoś na GLXie, ot choćby wystartuje glxinfo. Zatem zawartość mojego skryptu wygląda tak:

#!/bin/bash

glxinfo

/usr/bin/AfterShot3X64

Budowanie obrazu kontenera

    Do zbudowania obrazu kontenera w Fedorze służy buildah:

$  buildah bud -t aftershoot:3

Po tej operacji komenda podman images powinna pokazać coś takiego:

$ podman images            

REPOSITORY            TAG     IMAGE ID      CREATED       SIZE

localhost/aftershoot  3       b4ba6c8f9b47  3 hours ago   1.09 GB

registry.fedoraproject.org/fedora  31      a7a37f74ff86  8 months ago  199 MB

Start kontenera

    Pora uruchomić kontener. Tu dzieje się kilka  mniej oczywistych  rzeczy, bo uruchamiam aplikację, która ma wyświetlać coś na ekranie i to na dodatek z dostępem do sieci hosta, lokalnego katalogu i przede wszystkim karty graficznej. Dlatego w zaklęciu potrzeba kilku parametrów:

$ podman  run --net host --privileged --env "DISPLAY" --volume "$HOME/.Xauthority:/root/.Xauthority:rw" --volume "/etc/machine-id:/etc/machine-id"  --volume "/home/marcinek/Obrazy:/root/Pictures" localhost/aftershoot:3

    Po kolei:

  • net host - chcę, żeby kontener korzystał bezpośredni z sieci hosta.
  • privileged - kontener ma mieć dostęp do sprzętu, np karty graficznej.
  • en "DISPLAY" - przenieś zmienną $DISPLAY hosta do kontenera, żeby ten wiedział gdzie jest jego ekran X11.
  • volume "$HOME/.Xauthority:/root/.Xauthority:rw" - udostępnij plik autoryzacji do ekranu X11.
  • volume "/home/marcinek/Obrazy:/root/Pictures" - udostępnij mój katalog ze zdjęciami, żeby było na czym pracować :-)
Taaadaaam!

Sprzątanie po robocie

    Po skończonej robocie, kontener zostaje w stanie "exited". 

$ podman ps -a                                             

CONTAINER ID  IMAGE COMMAND    CREATED        STATUS                     PORTS   NAMES

98987600e9df  localhost/aftershoot:3  /start.sh  3 minutes ago  Exited (0) 16 seconds ago          kind_kowalevski


Sprząta się to tak:

$ podman container rm 98987600e9df                         

98987600e9dffa85521353d6be4b05081e7580afaed6063e39c18231edc260b1


P.S

    Zostało tu trochę miejsca na ulepszenia:
  • Można by zakombinować, żeby użytkownik wewnątrz kontenera to nie był root.
  • Wypadałoby podmapować jeszcze jakiś wolumen z licencją. W przeciwnym wypadku, każde uruchomienie programu uruchamia od nowa próbny okres licencyjny :-D 
  • Pewnie jest jakiś prstryk-elektryk, żeby kontener automatycznie znikał, gdy aplikacja się zakończy.
  • Mój laptop ma GPU a AfterShot potrafi korzystać z OpenCL, co jeszcze bardziej przyspieszy wołanie RAWów.

środa, 1 kwietnia 2020

IBM TS4500 + IBM 24B + QLogic 2562

Kolejna notatka z placu boju, tym razem z pewnego wdrożenia.

Klocki

Ugryzł mnie ostatanio w (_*_) taki zestaw:

  • IBM TS4500 z napędami LTO8
  • Dwa przełączniki Brocade (IBM 24B)
  • Dwa serwery Supermicro zgodne z IBM PC XT. Wyposażone w karty Qlogic QLE2562. Dwuportowe, 8 Gbit.
  • Maszyny pod RHEL 7.7 do tego dograny najnowszy (3.0.51-1) lin_tape.
  • Na jednym serwerze IBM Spectrum Protect 8.1.9.0, na obu klient BA + Storage Agent.
  • Oba serwery mają na sobie sporo dysków spiętych w rozproszony filesystem, a w zasadzie nakładkę na filesystem o nazwie dCache. Całość przechowuje sporo dużych, około 10GIB plików obrazowych (nie kompresują się). 
  • Wspomniany dCache, według zdefiniowanych reguł, woła sobie klienta B/A, żeby archiwizować bądź odtwarzać pliki z tego filesystemu. Taki HSM tylko Open Source.


Proste nie ? Gdyby było proste nie byłoby ciekawe. Zaraz po poskładaniu klocków okazało się, że performance jest tak... 3000 razy słabszy niż spodziewany: 100 KB/s zamiast spodziewanych 300 MB/s.

Diagnostyka

W takiej sytuacji zwykle zaczynam od najprostszych rzeczy: kable. Uszkodzone, z syndromem niedopchnięcia itd. 
Najpierw zajrzałem na przełączniki. portErrShow pokazał takie cuda:


fc-2:admin> porterrshow 
          frames      enc    crc    crc    too    too    bad    enc   disc   link   loss   loss   frjt   fbsy  c3timeout    pcs
       tx     rx      in    err    g_eof  shrt   long   eof     out   c3    fail    sync   sig                  tx    rx     err
  0:   13.0m   9.2m   9.2k   9.2k   9.2k   0      0     17     23.0m  14     12      0     12      0      0      0      0      0   
  1:    2.2k   1.4k   0      0      0      0      0      0    133.7k   2      6      0      6      0      0      0      0      0   
  2:  132.2k  11.9m   0      5      5      0      0      0     15.3m  10      4      0      3      0      0      0      0      0   
  3:   36.2k  34.8k   0      5      5      0      0      0     84.1k   8      5      0      4      0      0      0      0      0   
  4:    6.2m 136.7k   0      5      5      0      0      0    300.3k   8      5      0      5      0      0      0      0      0   
  5:    2.7m 285.4k   0      6      6      0      0      0     91.0k  10      3      0      5      0      0      0      0      0   
  6:   43.4k 625.0k   0      4      4      0      0      0     24.5k   6      1      0      3      0      0      0      0      0 

Na porcie 0 na 13 milionów ramek 23 miliony błędnych ?!? Zerknijmy na kabel:

2:admin> sfpshow 0
[...]
                                            Alarm                  Warn
                                    low         high       low         high
Temperature: 47      Centigrade      -5         85         0           80
Current:     7.098   mAmps           2.500      10.500     2.500       10.500 
Voltage:     3370.0  mVolts          3000.0     3600.0     3130.0      3460.0 
RX Power:    -10.9   dBm (80.4 uW)   31.5   uW  2000.0 uW  31.5   uW   790.0  uW
TX Power:    -2.2    dBm (600.1 uW)  126.0  uW  2000.0 uW  317.0  uW   790.0  uW


OK. Port wyłączony, urządzenia przeskanowane na nowo (odkryte na nowych ścieżkach, bo u klientu nie ma licencji na DPF). Następny test (drugi switch, bo pierwszy "port disabled"):

portErrShow pokazał, że większość błędów to "disc c3". Bez innych błędów, zwykle oznacza to, że ktoś nie chce odebrać pakietów, bo się np nie wyrabia. 
Patrząc na to co się działo na hoscie: podczas testu jeden korek całkowicie zawalony IO/Waitem, zacząłem podejrzewać karty FC..

Firmłer Qlogic

Jeśli do portu jest podłączony SAN to będzie działać takie zaklęcie:

# systool  -c fc_host -v -d host14
Class = "fc_host"

  Class Device = "host14"
  Class Device path = "/sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.0/host14/fc_host/host14"
    dev_loss_tmo        = "30"
    fabric_name         = "0x1000889471f05674"
    issue_lip           = <store method only>
    max_npiv_vports     = "254"
    node_name           = "0x20000024ff4e2996"
    npiv_vports_inuse   = "0"
    port_id             = "0x010100"
    port_name           = "0x21000024ff4e2996"
    port_state          = "Online"
    port_type           = "NPort (fabric via point-to-point)"
    speed               = "8 Gbit"
    supported_classes   = "Class 3"
    supported_speeds    = "1 Gbit, 2 Gbit, 4 Gbit, 8 Gbit"
    symbolic_name       = "QLE2562 FW:v8.07.00 DVR:v10.00.00.12.07.7-k"
    system_hostname     = ""
    tgtid_bind_type     = "wwpn (World Wide Port Name)"
    uevent              = 
    vport_create        = <store method only>
    vport_delete        = <store method only>

    Device = "host14"
    Device path = "/sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.0/host14"
      fw_dump             = 
      issue_logo          = <store method only>
      nvram               = "ISP "
      optrom_ctl          = <store method only>
      optrom              = 
      reset               = <store method only>
      sfp                 = ""
      uevent              = "DEVTYPE=scsi_host"
      vpd                 = "�)"

Od serwisu dowiedziałem się o istnieniu QConvergeConsole CLI/GUI, które potrafi pokazać coś takiego (tu wydruk po aktualizacji firmłeru):

# qaucli -i
Using config file: /opt/QLogic_Corporation/QConvergeConsoleCLI/qaucli.cfg
Installation directory: /opt/QLogic_Corporation/QConvergeConsoleCLI
Working dir: /root/ibm
--------------------------------------------------------------------------------
Host Name                      : arch1
HBA Instance                   : 0
HBA Model                      : QLE2562-S
HBA Description                : QLE2562 SUN StorageTek Enterprise 8Gb PCI-Express HBA Dual Port
HBA ID                         : 0-QLE2562-S
HBA Alias                      : 
HBA Port                       : 1
Port Alias                     : 
Node Name                      : 20-00-00-24-FF-4E-76-F2
Port Name                      : 21-00-00-24-FF-4E-76-F2
Port ID                        : 01-00-00
Principal Fabric WWN           : 10-00-88-94-71-F0-56-74
Adjacent Fabric WWN            : 20-00-88-94-71-F0-56-74
Serial Number                  : 0402T00-1318132856
Driver Version                 : 10.00.00.12.07.7-k
BIOS Version                   : 3.29
Running Firmware Version       : 8.08.01 (90d5)
Flash BIOS Version             : 3.29
Flash FCode Version            : 3.23
Flash EFI Version              : 6.09
Flash Firmware Version         : 8.01.02
Actual Connection Mode         : Point to Point
Actual Data Rate               : 8 Gbps
Supported Speed(s)             : 2 4 8 Gbps
Chip Model Name                : ISP2532-based 8Gb Fibre Channel to PCI Express HBA
PortType (Topology)            : NPort
Target Count                   : 5
PCI Bus Number                 : 175
PCI Device Number              : 0
PCI Function Number            : 0
PCI Device ID                  : 0x2532
Subsystem Device ID            : 0x0171
Subsystem Vendor ID            : 0x1077
PCIe Max Bus Width             : x8
PCIe Negotiated Width          : x4
PCIe Max Bus Speed             : 5.0 Gtps
PCIe Negotiated Speed          : 5.0 Gtps
HBA Temperature (C)            : N/A
HBA Status                     : Online
--------------------------------------------------------------------------------

No właśnie. W Linuxie jest tak śmiesznie zrobione, że potrafi zapakować firmware, bez zapisywania ich do flash'a karty. Takie firmłery w dużej mierze (np wszystkie QLAxxxx) przychodzą w systemowym pakiecie linux-firmware. Na stronie QLogic'a jest nowszy firmware niż w tym pakiecie. Założenie go wygląda na banalnie proste:
  • sciągamy pakiet qlogic-firmware
  • instalujemy z opcją --force, bo pliki gryzą się z tymi z linux-firmware
  • dokładamy konfig modułu qla2xxx tak, żeby chciał ładować firmare z pliku
# cat /etc/modprobe.d/qla2xxx.conf 
options qla2xxx ql2xfwloadbin=2
  • reboot
i... nic. 

Dlaczego? Bo qla2xxx jest ładowane z initrd. Czyli pik /etc/modprobe.d/qla2xxx.conf trzeba skopiować do /usr/lib/modprobe.d/qla2xxx.conf. A potem puścić:

# dracut -f

I gotowe. Nie mam za to pojęcia jak wrzucić ten firmware na stałe do pamięci flash karty. Myślałem, że może fwupdmgr to umie, ale nie. Przynajmniej nie w RHEL 7.


TS4500

W miedzyczasie założyłem support case w IBM i dostałem kilka dodatkowych wskazówek:
  • Zmienić domyślną topologię portów biblioteki z L-auto na N-port
  • Na przełącznikach, na portach napędów wyłączyć 
  • Kabelki mają być OM-3 (turkusowe). Na razie nie wiem na ile to ważne, mam pomarańczowe OM-1 albo 2. 

Przełączniki SAN

Wśród zaleceń jest taki cenny link. A sprowadza się on do ustawień:
  • Prędkość 8Gbit na sztywno.
  • Wyłączyć trunk port na portach które trunkiem być nie muszą.
  • Wyłączenie DFE, poprzez włączenie non-DFE: 
portCfgNonDfe --enable <port>
  • Czekam jeszcze na zalecenia co do wersji FOS'a

Morał


Jest taki: 

Zawsze sprawdzaj firmłery kart FC.  

To po wgraniu najnowszego, w pierwszym teście osiągnąłem 90 MB/s. Zadka nie urwało, bo LTO8 bez kompresji powinno szarpnąć 300. Po zaaplikowaniu większości poprawek zaleconych przez serwis, ten sam test pokazał 168 MB/s... zanim skończyły się dane testowe. 
Patrząc na portperfshow napęd się dopiero rozpędzał, bo pod koniec testu pokazywał transfery na poziomie 280 MB/s na porcie. 

niedziela, 21 października 2018

FSTRIM w Linuxie, KVM i gościach

W czym rzecz?

Mam dwa hosty KVMowe, na których pędzam rożne maszyny wirualne. Jeden z tych hostów to laptop, który z przyczyn oczywistych, jest poszyfrowany LUKSem. 
I od niego się wysztko zaczęło - używam go już od około 3 lat, no i ma dysk SSD. Ostatnio zaczęły mu się ostre zacięcia przy zapisach trwające nawet po kilka sekund. Po odrobinie googlania doszedłem do wniosku, że to pewnie trimowanie SSD. No i zacząłem borować temat, kikla razy się nawet od tego odbiłem - niby wszystko miałem a nie działało. Aż w końcu trafiłem na wyczerpujący artykuł. Nie będę tu przepisywał cudzej treści tylko ją zacytuję/zalinkuję.

Drugi problem jaki zauważyłem, to zajętość miejsca w obrazach dysków (używam cienkich, ale nie "sparse" qcow2). Otóż po jakimś czasie te obrazy wcale nie są takie cienkie wystarczy, że zrobię "dnf system-upgrade" na wirtualnej fedorze i już jest nadmuchana o dodatkowe 10 GiB. Windows Update robi podobne fiki-miki. 

Czyli, żeby trimować od maszyny wirtualnej, po dysk SSD hosta, trzeba przejść przez klika pięter stosu IO:



A konkretnie?

LUKS

Konkretnie, to trzeba zacząć od końca, czyli od crypttab'a na hoscie. Oczywiście jeżeli dysk hosta jest poszyfrowany, co gorąco polecam zwłaszcza dla laptopów. LUKS na Intelach pokazujących w /proc/cpuinfo flagę AES nie boli: i tak będzie sprzętowy.
U mnie zaszyfrowany jest cały dysk i wygląda to tak (lsblk):

NAME                                          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda                                             8:0    0   477G  0 disk 
├─sda1                                          8:1    0   500M  0 part  /boot
└─sda2                                          8:2    0 476,5G  0 part 
  └─luks-157fae7b-545b-4348-a02c-1b8a38110e33 253:0    0 476,5G  0 crypt
    ├─turing-root                             253:1    0    50G  0 lvm   /
    ├─turing-swap                             253:2    0   7,7G  0 lvm   [SWAP]
    └─turing-home                             253:3    0 418,8G  0 lvm   /home
sr0                                            11:0    1  1024M  0 rom  


Wystarczy zatem do /etc/crypttab dopisać to co poniżej zaznaczyłem na czerwono:

luks-157fae7b-545b-4348-a02c-1b8a38110e33 UUID=157fae7b-545b-4348-a02c-1b8a38110e33 none discard

piątek, 24 sierpnia 2018

Git: gałęzie (branch), także zdalne

Jednym z powodów, dla których zainstersowałem się Gitem jest możliwość synchronizacji repozytoriów pomiędzy komputermi. Drugim jest wygodna praca z rozgałęzieniami kodu (branch).
Oczywiście nic nie poszło tak szybko jak się spodziewałem, dlatego postanowiłem to opisać, żebym nie musiał tego odkrywać na nowo.

Cel ćwiczenia jest zatem następujący: W moim super-projekcie hello (patrz poprzedni wpis) na jednym komputerze utworzę gałąź kodu o nazwie my-hello gdzie utworzę moduł my_hello.{c|h}.
Gałęzie w ogóle są sensowną praktyką: Pracujesz nad jakąś funkcjonalnością - utwórz sobie gałąź. A jak uznasz, że jest ok, utwórz Pull-request, żeby inni mogli przejrzeć Twoje zmiany i je ewentualnie zatwierdzić.
Ale zanim zrobię pull-request, postaram się przesiąść na inny komputer, czyli będę musiał wypchnąc gałąź my-hello, a potem ją zsynchronizować na drugim komputerze.

Zaczynam od maszyny, gdzie klonuję mój projekt, co założy mi lokalne repozytorium w katalogu hello:

$ git clone https://github.com/stecenator/hello.git
Cloning into 'hello'...
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
$ cd hello/

$ ls -la
razem 32
drwxrwxr-x.  3 marcinek marcinek 4096 08-24 14:38 .
drwxrwxr-x. 13 marcinek marcinek 4096 08-24 14:38 ..
drwxrwxr-x.  8 marcinek marcinek 4096 08-24 14:38 .git
-rwxrwxr-x.  1 marcinek marcinek 8264 08-24 14:38 hello
-rw-rw-r--.  1 marcinek marcinek   73 08-24 14:38 hello.c
-rw-rw-r--.  1 marcinek marcinek    8 08-24 14:38 README.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working tree clean


Tworzę gałąź my-hello i modyfikuję kod:

$ git checkout -b my-hello
Switched to a new branch 'my-hello'
$ git status
On branch my-hello
nothing to commit, working tree clean

$ vim my_hello.h
$ vim my_hello.c
$ vim hello.c

$ git status
On branch my-hello
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   hello
    modified:   hello.c

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    my_hello.c
    my_hello.h

no changes added to commit (use "git add" and/or "git commit -a")
$ git add *.c *.h
$ git status
On branch my-hello
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   hello.c
    new file:   my_hello.c
    new file:   my_hello.h

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   hello


Na koniec pracy nad modułem commit i wypycham gałąź do githuba:

$ git commit -m "Dodanie modułu my_hello"
[my-hello 6b05f85] Dodanie modułu my_hello
 3 files changed, 12 insertions(+), 2 deletions(-)
 create mode 100644 my_hello.c
 create mode 100644 my_hello.h
 

$ git push -u origin my-hello
Username for 'https://github.com': stecenator
Password for 'https://stecenator@github.com':
Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/stecenator/hello.git
 * [new branch]      my-hello -> my-hello
Branch my-hello set up to track remote branch my-hello from origin.


A teraz idę do domu, odpalam drugą kompućkę i chcę znowu popracować nad tą gałęzią kodu. W tym celu muszę sobie przypomineć jakież to mam zdalne gałęzie na githubie:

Ponieważ na tej maszyne mam już repozytorium projektu hello, muszę tylko stanąć w katalogu tegoż i odświeżyć listę gałęzi kodu z githuba:

$ git fetch origin
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
From https://github.com/stecenator/hello
 * [new branch]      my-hello   -> origin/my-hello

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean


Gałąź jest już widoczna, ale git status pokazuje, że nadal pracuję na master. Ze zdalnymi gałęziami nie da się pracować. Ale można na ich podstawie utworzyć gałąź lokalną. Nawet o innej nazwie, ale to trochę szalony pomysł, więc będę się trzymał tej samej nazwy co na serwerze:

$ git checkout -b my-hello origin/my-hello
Branch 'my-hello' set up to track remote branch 'my-hello' from 'origin'.
Switched to a new branch 'my-hello'
$ ls
hello.c  my_hello.c  my_hello.h  README.md


Jak widać, w katalogu pojawiły się pliki z gałęzi my-hello utworzonej na kompie w pracy a następnie wypchniętej do Githuba.

Warto zapamiętać, że teraz mam  tak na prawdę 5 gałęzi my-hello: dwie lokalne na komputerach, dwa lokalnie zapamiętane obrazy, read-only origin/my-hello i w końcu główną origin/my-hello na Githubie.

Podsumowując, praca z gałęzią my-hello będzie wyglądać tak:
  • git fetch  - żeby zakutalizować repozytorium i lokalną kopię origin/my-hello.
  • git pull lub git checkout -b my-hello origin/my-hello  - utworzenie lokalnej gałęzi my-hello. git pull robimy, jeśli siedzimy już na gałęzi które jest Set to track remote branch, co się dzieje automatycznie jeśli choć raz zrobimy got checkout ze zdalnej :-D
  • chrum-chrum - czyli praca na kodzie z tej gałęzi.
  • git add - Wrzuca pliki do poczekalni commitu.
  • git commit - zapisuje zmiany w lokalnej gałęzi my-hello.
  • git push - aktualizuje lokalną i zdalną kopię origin/my-hello

wtorek, 21 sierpnia 2018

Git + Github jak krowie na miedzy czyli jak zacząć

Poziom bałaganu w wersjach, podwersjach, kopiach, smakach itd moich różnych skryptów w końu mnie przerósł i uznałem, że dojrzałem do używania gita i githuba. I oto co po 2 godzinach rozkminy udało mi się wykombinować na ich temat. Oczywiście trzeba się zarejestrować na github.com.
Zaczynam od utworzenia repozytorium na githubie, które reprezentuje mój projekt. Ja swój nazwałem hello
System zapoponował mi co mam z nim dalej zrobić:



Jako miłośnik command-line wybrałem bramkę nr 2 (można też nr 3, jesłi ktoś ma lokalne repozytorium gita i chce je wciśnąć w githuba) U mnie wersja nr 2 wygląda następująco:
Najpierw stworzyłem kilka plików

$ echo "# hello" >> README.md
$ git init
Initialized empty Git repository in /home/marcinek/prog/hello/.git/
$ vim hello.c
$ cat hello.c
#include <stdio.h>

int main()
{
    printf("Hello world!\n");
    return 0;
}
$ gcc -o hello hello.c
Projekt w zasadzie gotowy do zapakowania do Githuba:
 
$ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    README.md
    hello
    hello.c


nothing added to commit but untracked files present (use "git add" to track)

Na czerwono git zaznaczył pliki, które pojawiły się w lokalnym katalogu/repozytorium, które nie zostały do niego dodane. Żeby git raczył je śledzić, trzeba je dodać. Jeszcze nie wiem jak zrobić, żeby pliki dodawały się automatycznie, bo jakoś nie chce mi się wierzyć, żę Linus z palca dodał każdy z kilkuset tysięcy plików kernela, ale na razie robię to ze wspomnianego palca:

$ git add *
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   README.md
    new file:   hello
    new file:   hello.c


Teraz jest już lepiej. Można zacomitować:

$ git commit -m "Pierwszy comit"
[master (root-commit) 11ac7dc] Pierwszy comit
 3 files changed, 8 insertions(+)
 create mode 100644 README.md
 create mode 100755 hello
 create mode 100644 hello.c

Ale to jeszcze nie poszło w świat. Jest teraz w gałęzi: master:

$ git status
On branch master
nothing to commit, working tree clean


No to można spróbować wypchnąć repozytorium w świat:

$ git remote add origin https://github.com/stecenator/hello.git
$ git push -u origin master
Username for 'https://github.com': stecenator    
Password for 'https://stecenator@github.com':
Counting objects: 5, done.
Delta compression using up to 12 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 2.56 KiB | 2.56 MiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To https://github.com/stecenator/hello.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.



I gotowe!
A potem to już jest czysta zabawa:
  • Praca na wielu komputerach
  • Tworzenie rozgałęzień (branch)
  • Pull requesty (pewnie jest dużo ciekwiej, jak kilka osób pracuje nad jednym projektem)
  • Merge.
Może to kiedyś opiszę ? 

niedziela, 18 marca 2018

Klonowanie maszyn wirtualnych w KVM/Qemu

Jakiś czas temu postanowiłem wypiąć się na VMware (przyleci nowy kernel, i częto moduły do jądra nie chcą się kompilować) i przesiąść się na 100% open source. VirtualBox jakoś mi nie leży, poza tym Open Stack zaczął ostatnio dość mocno rządzić... Krótko mówiąc, wybór padł na KVM.
Owszem jest dość drewniany, nie jest tak wygodny jak VMware Player/Workstation czy choćby wspomniany VirtualBox, ale ma kilka unikalnych cech: Jest wmurowany w jądro, nie trzeba zatem nic rekompilować, integruje się z KSM co pozwala na solidny "overbooking" pamięci, jest elementem OpenStacka, ma command line i bez żadnego dodatkowego tańca deszczu, działa w trybie headless, czyli bez telewizora.

Czyż to nie jest zgrabne?:

sudo virsh start maszynka_wirtualna

Ale do rzeczy, ja dziś o klonowaniu, a konkretnie o jednym jego aspekcie: Linked clones. VMware pod tym względem nas mocno rozpieściło - ładny graficzny pająk pokazujący zależności pomiędzy migawkami, snapshoty, stan maszyny, a nie tylko dysków itd. W KVM tak nie ma. Linked clone dotyczy tylko dysków i w żadnym stopniu NIE CHRONI oryginału przed zmianami! Możliwy jest zatem następujący scenariusz:
  1. Tworzymy maszynę master.
  2. Tworzymy  połączonego z nią klona o nazwie clone.
  3. Uruchamiamy clone, coś na nim zmieniamy itd.
  4. Uruchamiamy master'a i coś nanim robimy.
  5. Clone szlag trafił.

Dlatego żeby uniknąć podobnej sytuacji, trzeba od razu podejśc do sprawy z pełną higieną, np.: oddzielna storage pula na "mastery", maszyny-szablony read-only, porządna dokumentacja itd. Można też dla bezpieczeństwa odłączyć obraz "master" od maszyny wirtualnej. Ale ja jak zwykle, na brudno:

Mam takie repozytoria:

$ sudo virsh pool-list --all
 Nazwa                Stan       Automatyczne uruchamianie
-------------------------------------------
 ajax                 nieaktywne tak      
 default              aktywne    tak      
 ISO                  aktywne    tak      
 os                   nieaktywne tak      
 os-1                 nieaktywne tak      
 removeable_seagate   nieaktywne tak      
 vm                   aktywne    tak    


Repo "removeable_seagate" jest na zewnętrznym HDD. Pula "vm" jest na wewnętrznym SSD. Dla wygody kolejne polecenia będą wykonane w interaktywnym shellu virsh:

virsh # pool-start removeable_seagate
Uruchomiono pulę removeable_seagate

virsh # vol-list removeable_seagate
 Nazwa                Ścieżka                              
------------------------------------------------------------------------------
 ARCUS.qcow2          /run/media/marcinek/Seagate_Enc/kvm/ARCUS.qcow2
 CentOS7-Generic.qcow2 /run/media/marcinek/Seagate_Enc/kvm/CentOS7-Generic.qcow2
 disk1.img            /run/media/marcinek/Seagate_Enc/kvm/disk1.img
 F24wrk.qcow2         /run/media/marcinek/Seagate_Enc

[ ... ]

Jak widać w puli removeable_seagate mam obraz o nazwie CentOS7-Generic.qcow2. To będzie mój master.
Do klonowania można użyć polecenia virsh: vol-clone ale z mojego punku widzenia ma dwie wady: klon powstaje w tej samej puli i albo utworzy pełną kopię, albo z opcją --prealloc-metadata powstanie plik rzadki (sparse), z którym niektóre programy, np do backupu, zachowując się dziwnie. dlatego użyję qemu-img. W shellu systemowym przechodzę to katalogu z pulą docelową i wołam klonowanie tak:

$ qemu-img create -f qcow2 \
-o backing_file=/run/media/marcinek/Seagate_Enc/kvm/CentOS7-Generic.qcow2 dns1.qcow2 

Formatting 'dns1.qcow2', fmt=qcow2 size=34359738368 backing_file=/run/media/marcinek/Seagate_Enc/kvm/CentOS7-Generic.qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16



Poprawiam prawa dostępu:

$ ls -la dns1.qcow2
-rw-r--r--. 1 marcinek qemu 197120 03-18 12:56 dns1.qcow2
$ chmod g+rw dns1.qcow2 



Jaki rozmiar ma moja nowa maszyna wirtualna ?

$ du -sm dns1.qcow2
1    dns1.qcow2

Teraz, np przy pomocy virtmanager'a tworzę maszynę wirtualną korzystającą z mojego sklonowanego dysku:

virsh # list
 Identyfikator Nazwa                          Stan
----------------------------------------------------
 1     dns1                           uruchomiona

virsh # dumpxml 1
<domain type='kvm' id='1'>
  <name>dns1</name>
  <uuid>6a95c7c7-94df-4a77-997e-d36bb169b66d</uuid>
  <title>DNS 1</title>
  <description>Testowy dns do zabaway z dynamic update</description>
  <memory unit='KiB'>1048576</memory>

[ ... ]
<disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/home/marcinek/vm/dns1.qcow2'/>
      <backingStore type='file' index='1'>
        <format type='raw'/>
        <source file='/run/media/marcinek/Seagate_Enc/kvm/CentOS7-Generic.qcow2'/>
        <backingStore/>
      </backingStore>
      <target dev='vda' bus='virtio'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
    </disk>


Po uruchomieniu i doinstalowaniu około 5MB pakietów, dysk-klon ma 21 MB.

środa, 10 stycznia 2018

Klient IBM Spectrum Protect w piaskownicy

Dlaczego Docker

Od jakiegoś czasu uważnie przyglądam się technologii kontenerów w różnych systemach operacyjnych. Zaczęlo się prawie 20 lat temu z Workload Managerem w AIXie, który potem przeszedł w WPARy. Gdzie po drodze obiły mi się jeszcze o uszy subsystemy w OS/400, kilka podejść w Linuxie (pierwsze w 2002 robione w... Polsce). W końcu technologia dojrzała, a świat dojrzał do niej: powszechna, wręcz chorobliwa wirtualizacja i aplikacje oparte o mikroserwisy.
Ja do tematu dojrzałem dziś, bo mnie do tego zmusiła jednym, prostym ruchem Matka Korporacja: Wraz z wprowadzeniem klienta TSM/Spectrum Protect w wersji 8.1.2 (i 7.8) praktycznie zerwano z kompatybilnością w dół. A póki co, 100% systemów klikeckich z którymi pracuję to 7.1.7.XXX i niższe. A ficzury z 8.1.3 i 4 nęcą i potestować by się chciało.
Sęk jednak w tym, że serwer 8.1.4 nie gada z klientem niższym niż 7.8. Teoretycznie, klient 7.8 i 8.1.X, gdzie X >=2 gada z niższymi serwerami, ale jak raz zobaczy się z "wyższym" to już z niczym innym gadać nie będzie. Czyli muszę mieć dwóch klinetów BA w systemie - 8.1.1 do pracy i 8.1.4 do zabawy. A tego producent nie przewidział.
Zwykle w takiej sytuacji klonuję moją roboczą Fedorę, instaluję co trzeba i tyle. Tym razem postawiłem na Dockera.

Jak zacząć?

  1. Mieć jakiegoś w miarę nowoczesnego linuxa na hoście. Ja mam Fedorkę 27.
  2. Nie czytać https://docs.docker.com/get-started/. 
  3. Przeczytać tę dokumentację, przynajmniej do ustępu o pomijaniu sudo.
  4. Rozpocząć zabawę z kontenerami.

A może jednak coś warto wiedzieć?

Mi wystarczyło mieć śwadomość następujących faktów, choć niektóre z nich uświadomiłem sobie "w boju":
  1. Kontener po zgaszeniu WRACA do oryginalnego stanu. Czyli nie ma tak, że odpalam sobie jakiś generyczny kontenerek z Fedorą (bardzo generyczny: bash, ls i dnf i kilka, w sumie 86MB innych programów), doinstalowuję co trzeba, gaszę i jak potrzebuję to odpalam.
  2. Kontener buduje się... na bazie innego kontenera. Ja postanowiłem użyć docker.io/fedora, który jest oficjalnym buildem fedory na Dockera.
  3. Kontener buduje się na podstawie Dockerfile. Tu jest dokumentacja z przykładowym plikiem.

Tworzenie kontenera

Sciągam podstawkę:

$ docker pull docker.io/fedora
Using default tag: latest
Trying to pull repository docker.io/library/fedora ...
sha256:25f7dac76b2c88d8b7e0b1d6213d3406e77c7f230bfa1e66bd1cbb81a944eaaf: Pulling from docker.io/library/fedora
a8ee583972c2: Pull complete
Digest: sha256:25f7dac76b2c88d8b7e0b1d6213d3406e77c7f230bfa1e66bd1cbb81a944eaaf
Status: Downloaded newer image for docker.io/fedora:latest

$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
docker.io/hello-world   latest              f2a91732366c        6 weeks ago         1.85 kB
docker.io/fedora        latest              422dc563ca32        7 weeks ago         252 MB






Zakładam pusty katalog na mój projekt:
$ mkdir -p /home/marcinek/containers/SPCliV8.1.4
$ cd  /home/marcinek/containers/SPCliV8.1.4
$  
Na początek trzeba przygotować pliki jakie będą używane do budowy  kontenera. Chcę zainstalować klienta Backup Archive (BA) w wersji 8.1.4. Mozna go sobie pobrać np stąd. Ja sobie stworzyłem katalog install gdzie wrzuciłem następujące pliki:
$ pwd
/home/marcinek/containers/SPCliV8.1.4

$ ls install/
8.1.4.0-TIV-TSMBAC-LinuxX86.tar        gskssl64-8.0.50.78.linux.x86_64.rpm  README.htm              TIVsm-APIcit.x86_64.rpm  TIVsm-BAhdw.x86_64.rpm  TIVsm-filepath-source.tar.gz
gskcrypt64-8.0.50.78.linux.x86_64.rpm  README_api.htm                       TIVsm-API64.x86_64.rpm  TIVsm-BAcit.x86_64.rpm   TIVsm-BA.x86_64.rpm     TIVsm-JBB.x86_64.rpm

No i tworzę plik Dockerfile: (na razie z błędem!)

FROM fedora
run mkdir -p /opt/tivoli/tsm/client/ba/bin
add install/ /install
add dsm.sys /opt/tivoli/tsm/client/ba/bin
add dsm.opt /opt/tivoli/tsm/client/ba/bin
#run echo "proxy=http://192.168.1.12:3128" >> /etc/dnf/dnf.conf
run echo "53.46.173.120 tsmservice" >> /etc/hosts
run dnf -y install iproute nfs-utils fuse-sshfs.x86_64 iputils
run dnf -y install /install/gsk* /install/TIVsm-API64.x86_64.rpm /install/TIVsm-BA.x86_64.rpm
run rm -rf /install
CMD /opt/tivoli/tsm/client/ba/bin/dsmadmc

 
A teraz budowanie:

$ docker build -t marcinek/ispcli_v814 .

No i odpalam:

$ docker run -it marcinek/ispcli_v814 /bin/bash
[root@ae505b4dd377 /]# cat /etc/hosts
127.0.0.1    localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
ff00::0    ip6-mcastprefix
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters
172.17.0.2    ae505b4dd377


Czyli qpa. Nie opisała się zmiana pliku /etc/hosts. Docker najwyraźniej tak ma, rozwiązań jest kilka. Można np uruchamiać contener z opcją --add-host=[].
No to spróbujmy:

$ docker run --add-host tsmservice:53.46.173.120 -it marcinek/ispcli_v814 cat /etc/hosts
127.0.0.1    localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
ff00::0    ip6-mcastprefix
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters
53.46.173.120    tsmservice
172.17.0.2    75fa3c6d2bce



Fantastik. To teraz jak zrobić, żeby się taka zmiana zapisała na poziomie budowania kontenera?

O tym napiszę poźniej, jak znajdę jakieś w miarę eleganckie rozwiązanie bo to co znajduje google nie jest ładne :-P
Brudne jest tu: http://jasonincode.com/customizing-hosts-file-in-docker/

I jeszcze poprawka

Kończyłem ten artykuł mając pod ręką serwer 7.1.7.300. Jak wróciłem do mojego 8.1.4 , okazało się... że nie działa:

dsmadmc -se=tasiemiec
IBM Spectrum Protect
Command Line Administrative Interface - Version 8, Release 1, Level 4.0
(c) Copyright by IBM Corporation and other(s) 1990, 2017. All Rights Reserved.

Enter your user id:  admin

Enter your password: 

ANS1592E Failed to initialize SSL protocol.
ANS8023E Unable to establish session with server.

ANS8002I Highest return code was -362.
Zła informacja jest taka, że w dsmerror.log'u znajdują się dokładnie te dwa wpisy z ekranu i nic więcej.  Pierwsza myśl. no to sobie włączę trace.  Konia z rzędem temu, kto znajdzie w internecie kompletną listę flag tracingu do klienta BA. Klasy i owszem, pojedynczych flag, nie. Ponieważ wybieram się pobiegać, to szybkie rozwiązanie, w stylu żeby pozbyć się gorączki należy wyrzucić termometr. Zmienić session security dla admina na którego chcę wejść moim kontenerem ze STRICT na TRANSACTIONAL:

 
I teraz można już wchodzić na admina z kontenera.
$ dsmadmc -se=tasiemiec
IBM Spectrum Protect
Command Line Administrative Interface - Version 8, Release 1, Level 4.0
(c) Copyright by IBM Corporation and other(s) 1990, 2017. All Rights Reserved.

Enter your user id:  admin

Enter your password: 

Session established with server TASIEMIEC: Linux/x86_64
  Server Version 8, Release 1, Level 4.000
  Server date/time: 01/13/18   10:28:38  Last access: 01/13/18   10:26:43


Protect: TASIEMIEC>q pr

Process      Process Description      Process Status                                  
  Number                             
--------     --------------------     -------------------------------------------------
       3     Local to Cloud           Cancelling Move Container of OVH. Elapsed time: 
              Transfer                 0 Days, 12 Hours, 54 Minutes.                  

Protect: TASIEMIEC>q stg

Storage         Device         Storage       Estimated       Pct       Pct      Hig-     Lo-     Next Stora-
Pool Name       Class Name     Type            Capacity      Util      Migr     h M-      w      ge Pool   
                                                                                 ig      Mi-    
                                                                                 Pct      g     
                                                                                         Pct    
-----------     ----------     ---------     ----------     -----     -----     ----     ---     -----------
BMIX                           CLOUD              400 G       0.0                                          
DIR_LOCAL                      DIRECTORY          400 G      20.1                                          
IBM_DEPLOY-     IBM_DEPLO-     DEVCLASS           0.0 M       0.0       0.0       90      70               
 _CLIENT_P-      Y_CLIENT-                                                                                 
 OOL             _IMPORT                                                                                   
OVH                            CLOUD            1,238 G       8.5       

A wracając do SSLa - spróbuję to rozkminić tak, żeby działało na domyślnym ustawieniu STRICT. Pewnie zacznę od tracingu serwera, bo tam jest bardzo obiecująca flaga SSLINFO...