Linux w stanie pożądanym
Dziś słów kilka o tym, jak przy pomocy PowerShella i Windowsa zarządzać (na razie na dość podstawowym poziomie) Linuxem. Posłużymy się przy tym jednym z nowszych narzędzi, którego premiera związana jest z Windows Server 2012 R2: PowerShell Desired State Configuration (w skrócie: DSC). Po drugiej zaś stronie nasze zabiegi wspierać będzie inna, nieco starsza technologia: Open Management Infrastructure (w skrócie: OMI), która po raz pierwszy została objawiona światu w roku 2012. Rozpoczniemy od “gołego” Linuxa, na którym następnie zainstalujemy wszystkie prerekwizyty oraz obie niezbędne paczki: OMI i PowerShell DSC dla Linuxa, by wreszcie “przećwiczyć” na tak przygotowanej maszynie wszystkie, dostępne obecnie zasoby.
Instalacja – Linux
W moich testach korzystałem z CentOS-a w wersji 6.5: w czasie rozmaitych przygód z Linuxami korzystałem właśnie z tej dystrybucji, więc by nie tracić zbyt wiele czasu na przyswajanie niuansów “pingwinka”, również tym razem po nią sięgnąłem. Różnica, która okazała się dość istotna (ale o tym nieco później), to język instalacji: zwykle wybieram wersję angielską, na potrzeby tego artykułu skorzystałem z wersji polskiej. Po instalacji najbardziej podstawowej dorzucić musiałem kilka pakietów wymaganych przez OMI:
yum -y groupinstall 'Development Tools' yum -y install pam-devel yum -y install openssl-devel yum -y install python yum -y install python-devel
Instalacja – OMI
Następnie konieczne było ściągnięcie “źródełek”. W pierwszej kolejności ściągnąłem i zainstalowałem OMI:
su cd ~ mkdir build mkdir logs cd build wget https://collaboration.opengroup.org/omi/documents/30532/omi-1.0.8.tar.gz tar -xvf omi-1.0.8.tar.gz cd omi-1.0.8 ./configure --bindir=/usr/bin | tee ~/logs/omi-configure.log make | tee ~/logs/omi-make.log make install | tee ~/logs/omi-make-install.log
Zmieniłem (jak widać) miejsce, gdzie po instalacji trafiają binaria. Domyślnie trafiłyby one do folderu, którego nie ma w zmiennej $PATH. Musielibyśmy więc albo zmienną tą zmodyfikować, albo uruchamiać podając pełną ścieżkę.
Instalacja – Linux DSC
Drugi element, który należy ściągnąć, to źródła zawierające dostawców dla Linuxa, z których następnie będziemy korzystać. Istotne jest, że do poprawnego skompilowania konieczne jest posiadanie źródeł OMI wewnątrz folderu ze źródłami naszych dostawców. Moim zdaniem to niedopatrzenie: powinna być możliwość skorzystania ze skryptu ‘configure’, by podać ścieżkę inną niż domyślna i przekierować kompilator do odpowiedniego folderu. Na razie jednak zadbamy o to, by źródła znalazły się w folderze ‘build’, w którym znajdują się źródła OMI:
cd ~/build wget https://github.com/MSFTOSSMgmt/WPSDSCLinux/releases/download/v1.0.0-CTP/PSDSCLinux.tar.gz tar -xvf PSDSCLinux.tar.gz cd dsc/ mv * ~/build cd ~/build make | tee /tmp/dsc-make.txt make reg | tee /tmp/dsc-make-reg.txt
Pozostaje jedynie skonfigurować odpowiednio iptables (wpuszczając WSMANS) i uruchomić serwer OMI:
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport wsmans -j ACCEPT omiserver -d
Linux jest skonfigurowany, wracamy więc do PowerShella i próbujemy nawiązać z nim pierwsze połączenie:
$rootPassword = ConvertTo-SecureString -AsPlainText -Force -String 'P@$$w0rd' $linuxParams = @{ ComputerName = 'centosPL.bielawscy.com' Credential = New-Object pscredential -ArgumentList root, $rootPassword Authentication = 'Basic' SessionOption = New-CimSessionOption -UseSsl -SkipCACheck -SkipCNCheck -SkipRevocationCheck } $cimLinux = New-CimSession @linuxParams
Sprawdźmy dla pewności, czy faktycznie “rozmawiamy” z naszym Linuxem (korzystamy przy tym z klasy OMI_Identify):
Widać tu już nie tylko typ systemu, wprowadzoną przez nas zmianę w ścieżce binariów, ale również przestrzeń nazw, która wygląda obiecująco.
Instalacja – moduł nx
By móc skorzystać z zasobów na Linuxie, nasz system musimy umieć stworzyć odpowiednie pliki konfiguracyjne. Podobnie jak w przypadku innych, niestandardowych zasobów, musimy na komputerze używanym do tworzenia konfiguracji posiadać odpowiedni moduł, który zasoby te opisuje. W tym celu ze strony projektu pobieramy moduł “nx” i rozpakowujemy tam, gdzie PowerShell bez trudu go odnajdzie. Czy PowerShell poprawnie widzi wszystkie zasoby sprawdzić możemy poleceniem Get-DscResource:
Próbna konfiguracja
Pozostaje więc stworzyć konfigurację i spróbować ją przesłać na naszego Linuxa. Zaczniemy od stosunkowo prostego zasobu: nxFile, dzięki któremu tworzyć możemy pliki na zdalnym komputerze:
configuration PierwszyTest { param ( [String]$ComputerName ) Import-DscResource -Module nx node $ComputerName { nxFile Test { DestinationPath = '/tmp/demo' Contents = "Losowy tekst...`n" Owner = 'bielawb' Mode = '660' } } } PierwszyTest -ComputerName centosPL.bielawscy.com Start-DscConfiguration -CimSession $cimLinux -Path .\PierwszyTest -Wait
Możemy przekonać się, że istotnie, plik na zdalnym komputerze powstał, ma wybranego przez nas właściciela i uprawnienia, a jego treść pokrywa się z wymaganą:
Zasoby i problemy
W chwili obecnej dostępnych jest pięć zasobów: nxUser do tworzenia użytkowników, nxGroup do tworzenia grup, nxService do zarządzania demonami, nxFile z którym się już zmierzyliśmy i wreszcie nxScript, dzięki któremu możemy oskryptować wszystko to, co jeszcze nie jest dostępne “z pudełka”. Trzy zasoby: nxFile, nxUser and nxGroup są praktycznie bezproblemowe. Skupię się więc na dwóch, z którymi przyszło mi się nieco pozmagać.
nxScript a Shebang
W ostatnim czasie miałem przyjemność poskryptować nieco w Pythonie. Gdy więc miałem napisać pierwszą konfigurację z wykorzystaniem skryptów, zdecydowałem się skorzystać właśnie z tego języka skryptowego. Z początku miałem kłopot: jak zmusić skrypt, by przy sprawdzaniu konfiguracji zwrócił False/True. Próbowałem na kilka sposobów:
- zwykła instrukcja ‘print’
- metoda ‘sys.stdout()’
- metoda ‘sys.exit()’
- raise
Moje testy często zawodziły, jak się później okazało jednak, wynikało to nierzadko z faktu, że skrypty postanowiłem “upiększyć”. Linux niestety nie toleruje estetycznej pustej linii na początku skryptu, jeśli korzystamy z języka innego niż język bieżącej powłoki. Aby problem zademonstrować, stwórzmy kilka skryptów na Linuxie, zarówno poprawnie jak i błędnie oznaczonych:
Jak widać tylko pierwszy ma instrukcję dla powłoki (tzw “Shebang”) we właściwym miejscu, na samym początku skryptu. Sprawdźmy, jaki będzie skutek:
Ponieważ skrypty uruchamiałem z poziomu basha, skrypt napisany w języku zrozumiałym dla tej powłoki zadziałał poprawnie nawet mimo tego, że informacja o interpreterze nie została odnaleziona. Inaczej sprawa się ma z Pythonem: skrypt “wykłada się” na instrukcji print, której w bashu nie ma. Ma to bezpośredni wpływ na konfigurację. Dla przykładu: w obecnej implementacji następująca konfiguracja nigdy nie dojdzie do skutku, właśnie przez problemy związane z niewłaściwym umiejscowieniem shebanga:
configuration LinuxDscDemo { param ( [string]$ComputerName ) Import-DscResource -Module nx Node $ComputerName { nxScript SimpleScript { TestScript = @' #!/usr/bin/python import os, sys from datetime import datetime file = '/tmp/script' if not os.path.exists(file): sys.exit(1) mtime = os.stat(file)[8] diff = datetime.now() - datetime.fromtimestamp(mtime) if diff.seconds > 300: sys.exit(1) sys.exit(0) '@ GetScript = @' #!/usr/bin/python print 'Good!' '@ SetScript = @' #!/usr/bin/python from datetime import datetime file = '/tmp/script' with open(file, 'a') as fileHandle: fileHandle.write("last modified: %s\n" % str(datetime.now())) '@ User = 'root' } } }
Przy próbie uruchomienia tej konfiguracji uzyskamy niezbyt wylewny komunikat o błędzie (logi w /opt/omi*/var/log/dsc.log też niewiele nam pomogą):
Wystarczy jednak, że usuniemy puste linie na początku herestringów definiujących nasze skrypty i konfiguracja automagicznie zacznie działać.
nxService a sprawa polska
Drugi problem pojawił się dopiero w trakcie pisania tego artykułu. Długo zachodziłem w głowę czemu nxService działa poprawnie na linuxie angielskim, a wykłada się na polskim. Pomijam fakt, że najpierw musiałem ustalić, że to właśnie ten zasób sprawia mi problemy (nie trudno pewnie odgadnąć, że najpierw sporo czasu poświęciłem nxScript…). Odpowiedź jest prozaiczna: typowy dla kolegów zza wielkiej wody anglo-centryzm. Wszystkie zasoby pisane były przy założeniu, że nasz linux będzie “amerykancki”. nxService nie sprawdza lokalizacji, ani też nie reaguje na nią. Stąd problem, gdyż implementujący ten zasób skrypt porównuje informacje zwracane przez service i chkconfig z angielskimi ciągami znaków (odpowiednio: “running” i “on”). Problem w tym, że na polskim linuxie się ich nie uświadczy:
By problem ten “naprawić” (bez ingerencji w implementację DSC) musielibyśmy “przestawić” lokale na te, których DSC oczekuje (np. modyfikując plik /etc/sysconfig/i18n). Alternatywa (moim zdaniem jedyna słuszna) to sprawić, by DSC nie zakładało lokali, a samo je wymuszało. Niestety, o ile ‘chkconfig’ jest “posłuszny”, o tyle ‘service’ już nie. Ten drugi musimy więc zastąpić wywołaniem ‘/etc/init.d/NazwaDemona’:
Naprawa u źródeł
Oba problemy (ten z nxService, jak i ten z nxScript) nie wymagają wiele pracy. Postanowiłem więc skorzystać z faktu, że pakiet Linux DSC dostępny jest na GitHubie. Stworzyłem własne “odgałęzienie” a następnie wprowadziłem obie poprawki, dzięki czemu skrypty mogę pisać w dowolny sposób (o ile oczywiście shebang będzie pierwszą linią “niepustą” w przesyłanym kodzie). Nie muszę też zmieniać języka, w jakim działa mój Linux: przez dwie niewielkie zmiany w nxService zasób ten powinien działać na dowolnym języku (choć testowałem go jedynie na dostępnym i zrozumiałym dla mnie języku polskim). Porównanie wersji “oficjalnej” i tej, po wprowadzonych przeze mnie zmianach można znaleźć na GitHubie. A jeśli będziecie chcieli przetestować wersję nieco poprawioną, to zmodyfikować musicie nieco procedurę instalacji:
wget https://github.com/bielawb/WPSDSCLinux/archive/master.zip unzip master cd WPSDSCLinux/dsc mv * ~/build cd ~/build make | tee /tmp/dsc-make.txt make reg | tee /tmp/dsc-make-reg.txt
Kompletny kod konfiguracji, której używałem do testów, umieściłem na GitHub gist. Być może, że również i ona znajdzie się w mojej wersji Linux DSC. Folder, z przykładowymi konfiguracjami, który jest w niej dostępny obecnie, jest prawie pusty. Z całą pewnością dobrze byłoby go zapełnić choć jednym przykładem dotyczącym każdego z dostępnych dostawców…