Linux w stanie pożądanym

Tux-ElegantDziś 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):

PowerShell-Pierwsze-Polaczenie-z-Linux-OMI-z-DSC

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:

Kontrolowanie-Zasobow-PowerShell-DSC-nx

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ą:

Testowe-Uruchomienie-Linux-DSC-nxFile

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:

Linux-Trzy-Skrypty-Sh-Python

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:

Linux-Problem-z-Shebang-Python

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ą):

nxScript-Problem-z-Pusta-Linia

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:

 Linux-pl_PL-service-chkconfig

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’:

Linux-pl_PL-adhoc-na-en_US-service-initd-chkconfig

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…

~ - autor: Bartek Bielawski w dniu Sierpień 31, 2014.

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

 
%d blogerów lubi to: