Aby osiągnąć pełną automatyzację procesu instalacji i konfiguracji systemu operacyjnego na urządzeniach wykorzystano
Aby osiągnąć pełną automatyzację procesu instalacji i konfiguracji systemu operacyjnego na urządzeniach wykorzystano
serwer PXE, stworzony z serwera TFTP (tftp-hpa), serwera DHCP (dhcp-isc-server) oraz serwera HTTP (apache2), a także narzędzie
serwer PXE, stworzony z serwera TFTP (tftp-hpa), serwera DHCP (dhcp-isc-server) oraz serwera HTTP (Apache2), a także narzędzie
cloud-init do automatycznego przeprowadzenia procesu instalacji systemu operacyjnego nadzorcy oraz narzędzie Ansible, do pełnej
cloud-init do automatycznego przeprowadzenia procesu instalacji systemu operacyjnego nadzorcy oraz narzędzie Ansible, do pełnej
konfiguracji systemu operacyjnego zarządcy.
konfiguracji systemu operacyjnego zarządcy.
@ -1049,7 +1049,7 @@ znów pojawia się ekran wyboru obrazu maszyny.
\end{figure}
\end{figure}
\paragraph{Bezpieczeństwo - zarządzanie obrazami}
\paragraph{Bezpieczeństwo - zarządzanie obrazami}
Każde zapytanie do serwera zarządcy obrazów musi być zautoryzowane. Odbywa sie to poprzez token JWT, który klient wysyła
Każde zapytanie do serwera zarządcy obrazów musi być zautoryzowane. Odbywa sie to poprzez token JWT (JSON Web Token), który klient wysyła
z każdym zapytaniem do serwera. Proces instalacji systemu bazowego i konfiguracji nie jest jednak chroniony,
z każdym zapytaniem do serwera. Proces instalacji systemu bazowego i konfiguracji nie jest jednak chroniony,
jeżeli w sieci znajdują się maszyny, które uruchomią się poprzez PXE, mogą zainstalować podstawową konfigurację systemu.
jeżeli w sieci znajdują się maszyny, które uruchomią się poprzez PXE, mogą zainstalować podstawową konfigurację systemu.
Nie posiada ona jednak aplikacji klienckiej, ani żadnej konfiguracji, jedynie klucz publiczny SSH, wymagany do wykonania
Nie posiada ona jednak aplikacji klienckiej, ani żadnej konfiguracji, jedynie klucz publiczny SSH, wymagany do wykonania
@ -1285,6 +1285,162 @@ class Server:
\label{fig:requireauth:listings}
\label{fig:requireauth:listings}
\end{figure}
\end{figure}
\paragraph{}
Serwer wystawia następujące punkty końcowe (ang. endpoints):
\begin{itemize}
\item GET \texttt{/} - przedstawia podstawowe dane o serwerze: nazwę, wersję oraz nazwę hosta, przykład odpowiedzi podano w listingu \ref{fig:response-main}
\item POST \texttt{/login} - pozwala na zalogowanie się poprzez wysłanie nazwy użytkownika i hasła, zwraca token JWT służący do autoryzacji, id użytkownika oraz jego nazwę jako potwierdzenie, przykład ciała zapytania logowania pokazano w listingu \ref{fig:request-login}, przykłady możliwych odpowiedzi pokazano w listingu \ref{fig:response-login}
\item POST \texttt{/clients} - pozwala na rejestrację klienta, przykład wymaganego ciała zapytania pokazano w listingu \ref{fig:response-register}
\item PUT \texttt{/clients} - pozwala na modyfikację danych o już zarejestrowanym kliencie, zapytania i odpowiedzi są takie same, jak dla żądań rejestracji klientów
\item GET \texttt{/clients/adres\_mac} - pozwala na pobranie danych o zadanym kliencie z serwera, możliwe odpowiedzi pokazano w listingu \ref{fig:response-client-data-get}
\item GET \texttt{/clients/adres\_mac/vms} - pozwala na pobranie listy numerów id obrazów przypisanych do klienta o podanym adresie MAC, możliwe odpowiedzi ukazano w listingu \ref{fig:response-list-vms}
\item GET \texttt{/images/id\_obrazu} - pozwala na pobranie danych o obrazie o zadanym numerze id, możliwe odpowiedzi pokazano w listingu \ref{fig:response-get-image-data}
\item GET \texttt{/images/id\_obrazu/download} - pozwala na pobranie obrazu o zadanym numerze id
\end{itemize}
\begin{figure}[hb]
\centering
\begin{lstlisting}
HTTP200:
{
"server_name": "VALHALLA",
"server_version": "v0.0.1",
"host": "127.0.0.1"
}
\end{lstlisting}
\caption{Przykład możliwej odpowiedzi na zapytanie pod punkt końcowy /}
\label{fig:response-main}
\end{figure}
\begin{figure}[hb]
\centering
\begin{lstlisting}
{
"username": "user",
"password": "sekret_password"
}
\end{lstlisting}
\caption{Przykład prawidłowego ciała żądania logowania}
\label{fig:request-login}
\end{figure}
\begin{figure}[hb]
\centering
\begin{lstlisting}
HTTP202 (poprawne dane):
{
"token": "xxxxxxxxx",
"user_id": "1",
"username": "user"
}
HTTP401 (niepoprawne dane):
{
"data": null,
"error": "Auth error",
"message": "Invalid login data"
}
\end{lstlisting}
\caption{Możliwe odpowiedzi na żądanie logowania od serwera}
\label{fig:response-login}
\end{figure}
\begin{figure}[hb]
\centering
\begin{lstlisting}
Poprawne zapytanie:
{
"mac_address": "00:00:00:00:00:00:00:62",
"ip_address": "192.168.1.12",
"hostname": "test",
"client_version": "v0.0.1alpha",
"vm_list_on_machine": []
}
Odpowiedz: HTTP201
{
"success": true
}
Niepoprawne zapytanie:
{
"mac_address": "00:00:00:00:00:00:00:62",
"ip_address": "192.168.1.12",
"client_version": "v0.0.1alpha",
"vm_list_on_machine": []
}
Odpowiedz: HTTP400
{
"data": null,
"error": "'hostname'",
"message": "Internal server error"
}
\end{lstlisting}
\caption{Możliwe zapytania i odpowiedzi serwera na żądanie rejestracji klienta}
\label{fig:response-register}
\end{figure}
\begin{figure}[hb]
\centering
\begin{lstlisting}
HTTP200 (istniejacy adres MAC):
{
"client_version": "v0.0.1alpha",
"hostname": "test",
"ip_address": "192.168.1.12",
"mac_address": "00:00:00:00:00:00:00:62"
}
HTTP404 (nieistniejacy adres MAC):
{
"data": null,
"error": null,
"message": "Client not found in database"
}
\end{lstlisting}
\caption{Możliwe odpowiedzi serwera na zapytanie o dane zadanego klienta}
\label{fig:response-client-data-get}
\end{figure}
\begin{figure}[hb]
\centering
\begin{lstlisting}
HTTP200 (istniejacy adres MAC):
[
1
]
HTTP404 (nieistniejacy adres MAC):
{
"data": null,
"error": null,
"message": "Client not found in database"
}
\end{lstlisting}
\caption{Mozliwe odpowiedzi serwera na zapytanie o obrazy przypisane do zadanego hosta}
\label{fig:response-list-vms}
\end{figure}
\begin{figure}[hb]
\centering
\begin{lstlisting}
HTTP200 (instniejacy obraz):
{
"image_file": "ubuntu.qcow2",
"image_hash": "dbdc4d7f10511387ef89ffc503080b92",
"image_id": "1",
"image_name": "ubuntu22",
"image_name_version_combo": "ubuntu22@v1.0.0",
"image_version": "v1.0.0"
}
HTTP404 (nieistniejacy obraz):
{
"data": null,
"error": null,
"message": "Image not found in database"
}
\end{lstlisting}
\caption{Możliwe odpowiedzi serwera na zapytanie o dane zadanego obrazu}
\label{fig:response-get-image-data}
\end{figure}
\paragraph{}
\paragraph{}
Ostatnim ważnym komponentem aplikacji jest klasa \texttt{ServerConfig}. Odpowiada ona za odczyt i parsowanie plików konfiguracyjnych
Ostatnim ważnym komponentem aplikacji jest klasa \texttt{ServerConfig}. Odpowiada ona za odczyt i parsowanie plików konfiguracyjnych
oraz odczytanie wartości ustawionych zmiennych środowiskowych i nadpisanie odpowiednich wartości w konfiguracji.
oraz odczytanie wartości ustawionych zmiennych środowiskowych i nadpisanie odpowiednich wartości w konfiguracji.
@ -1312,71 +1468,115 @@ Aplikacja klienta została podzielona na klika podstawowych modułów:
\end{itemize}
\end{itemize}
\paragraph{}
\paragraph{}
Sprawdzenie danych o maszynie odbywa się w kilku krokach: aby pobrać adres IP maszyny, program nawiązuje połączenie z serwerem
DNS Google (adres IP: \texttt{8.8.8.8}), a następnie sprawdza nazwę gniazda (ang. socket), które połączyło się z siecią.
Adres MAC jest sprawdzany przez bibliotekę \texttt{get\_mac\_address}, liczba rdzeni procesora przez bibliotekę \texttt{os}, a
ilość pamięci RAM poprzez bibliotekę \texttt{psutil} (bibiloteka zwraca liczbę bajtów pamięci, a reszta aplikacji wymaga liczby gigabajtów, stąd wymagana była konwersja).
Implementacja tych funkcjonalności, wraz z odczytem i parsowaniem plików konfiguracyjnych, znajduje się w klasie \texttt{MachineData}
\paragraph{}
Obsługa komunikacji z serwerem została umieszczona w klasie \texttt{ValhallaServer}. Za pomocą biblioteki \texttt{requests}
wysyłane są zapytania do serwera. Jeżeli wygaśnie token JWT, wysyłane jest zapytanie służące do zalogowania się do systemu,
a następnie ponawiane jest poprzednie zapytanie. Dane z serwera są przekazywane w formacie JSON.
Zaraz po uruchomieniu aplikacji klienckiej wysyłane jest żądanie rejestracji maszyny, lub, jeżeli maszyna już jest zarejestrowana,
następuje aktualizacja danych o maszynie. Następnie pobierana jest lista obrazów przypisanych do konkretnej maszyny, a same obrazy są pobierane.
Wszystkie te operacje są obsługiwane przez klasę \texttt{ValhallaServer}.
% Jeśli „Specyfikacja wewnętrzna”:
\paragraph{}
%\begin{itemize}
Obsługa uruchamiania maszyn wirtualnych sprowadza się do skopiowania pliku-wzorca skryptu uruchamiającego maszynę wirtualną QEMU do odpowiedniego
%\item przedstawienie idei
katalogu, podmianie tymczasowych wartości liczby rdzeni, ilości pamięci RAM i ścieżki do obrazu dysku maszyny na prawidłowe wartości
%\item architektura systemu
wyznaczone przez program w klasie \texttt{MachineData} oraz na podstawie danych obrazów pobranych z serwera,
%\item opis struktur danych (i organizacji baz danych)
nadaniu odpowiednich uprawnień dla pliku skryptu (bit wykonywalności - execute) oraz na uruchomieniu skryptu i zablokowaniu wykonywania aplikacji.
Najważniejszy fragment pliku konfiguracyjnego serwera DHCP zawarto w listingu \ref{fig:config-dhcp}. Ustawia on wskaźnik na serwer TFTP serwujący
%\end{itemize}
pliki wymagane do uruchomienia środowiska instalacyjnego.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Pakiet minted wymaga odkomentowania w pliku config/settings.tex %
%% importu pakietu minted: \usepackage{minted}%
%% i specjalnego kompilowania: %
%% pdflatex -shell-escape praca %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
% Krótka wstawka kodu w linii tekstu jest możliwa, np. \lstinline|int a;| (biblioteka \texttt{listings})% lub \mintinline{C++}|int a;| (biblioteka \texttt{minted})
% .
% Dłuższe fragmenty lepiej jest umieszczać jako rysunek, np. kod na rys \ref{fig:pseudokod:listings}% i rys. \ref{fig:pseudokod:minted}
CustomLog \${APACHE_LOG_DIR}/ks-server.example.com-access_log common
<Directory /ks>
Options Indexes MultiViews
AllowOverride All
Require all granted
</Directory>
<Directory /images>
Options Indexes MultiViews
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
\end{lstlisting}
\caption{Fragment konfiguracji serwera Apache2}
\label{fig:config-apache}
\end{figure}
% TODO
% TODO
\chapter{Weryfikacja i walidacja}
\chapter{Weryfikacja i walidacja}
@ -1394,54 +1594,133 @@ W ramach drugiej fazy testów ręcznie wymuszano proces synchronizacji zmian z s
pracującej pod kontrolą systemu Ubuntu Linux w wersji 22.04 LTS wraz ze środowiskiem graficznym Gnome. Obraz dysku zajmował
pracującej pod kontrolą systemu Ubuntu Linux w wersji 22.04 LTS wraz ze środowiskiem graficznym Gnome. Obraz dysku zajmował
12GB. Podczas tych testów sprawdzano czas potrzebny na pobranie przykladowego obrazu, korzystając z gigabitowej karty sieciowej, dostępnej w maszynie.
12GB. Podczas tych testów sprawdzano czas potrzebny na pobranie przykladowego obrazu, korzystając z gigabitowej karty sieciowej, dostępnej w maszynie.
Do pomiaru czasu wykorzystano narzędzie \texttt{time}, dostępne w większości systemów wywodzących się z rodziny UNIX.
W ramach trzeciej fazy testów, poddano ocenie wydajność i odczucia płynące z używania maszyny wirtualnej.
W ramach trzeciej fazy testów, poddano ocenie wydajność i odczucia płynące z używania maszyny wirtualnej.
\begin{itemize}
\paragraph{Pomiary czasu}
\item sposób testowania w ramach pracy (np. odniesienie do modelu V)
Pomiary czasu, w jakim urządzenie przeprowadzało instalację, powtórzono dziesięciokrotnie. Wyniki zostały przedstawione w tabeli \ref{id:tab:czas-konfiguracja}.
\item uzyskane wyniki w świetle postawionych celów i zdefiniowanych wyżej wymagań
%\item uzyskane wyniki w świetle postawionych celów i zdefiniowanych wyżej wymagań
\item kierunki ewentualnych danych prac (rozbudowa funkcjonalna …)
%\item kierunki ewentualnych danych prac (rozbudowa funkcjonalna …)
\item problemy napotkane w trakcie pracy
%\item problemy napotkane w trakcie pracy
\end{itemize}
%\end{itemize}
\paragraph{}
Uzyskano prawie pełną automatyzację procesu instalacji systemu nadzorcy. Administrator musi wykonać jedynie 4 manualne kroki:
dodanie adresów MAC obsługiwanych maszyn do konfiguracji serwera DHCP i konfiguracji skryptów Ansible, wywołanie komendy wysyłającej ,,magic packet'' do
wyznaczonych urządzeń, potwierdzenie instalacji na każdym z urządzeń oraz wywołanie skryptu Ansible do konfiguracji urządzeń.
Dzięki wykorzystaniu QEMU udało się zapewnić użycie maszyn wirtualnych oraz łatwość tworzenia własnych obrazów dla nich. Osiągnięto
także ,,bezstanowość'', maszyny wirtualne po restarcie wracają do swojego pierwotnego stanu sprzed wszsytkich zmian wprowadzonych
przez ostatniego użytkownika.
Użycie PXE, cloud-init oraz Ansible jako systemu automatyzującego instalację systemu nadzorcy pozwoliło na zapewnienie
modularności i możliwości wbudowania rozwiązania w już istniejącą architekturę sieciową.
\paragraph{}
Niestety wydajność systemu zarządzania obrazami maszyn nie jest satysfakcjonująca. Największym problemem obecnego rozwiązania jest
konieczność załadowania całego wysyłanego pliku do pamięci aplikacji, przez co wydajność jest mocno ograniczona. Dobrym rozwiązaniem tego
problemu byłoby zintegrowanie serwera aplikacji z serwerem Apache2, lub Nginx, gdzie to dedykowany serwer HTTP wysyłałby duże pliki,
a serwer zarządzający obsługiwałby tylko przechowywanie danych. Ciekawym rozwiązaniem tego problemu byłoby też użycie narzędzia rsync,
którego zaawansowane wykrywanie różnic w plikach i podmiana jedynie tych właśnie róznic na pewno znacząco przyspieszyłoby
działanie serwera obrazów. Kolejnym problemem jest kwestia bezpieczeństwa. Aby możliwe było pełne zautomatyzowanie procesu
zdecydowano się na użycie tylko jednego użytkownika dla wszystkich klientów. Jest to duże ryzyko ze względów bezpieczeństwa,
ponieważ potencjalny atakujący może wtedy odczytać adresy MAC wszystkich urządzeń i podszywać się pod nie.
\paragraph{}
Podobnie jak w przypadku serwera, wydajność systemu w maszynach wirtualnych nie jest satysfakcjonująca. Największym problemem jest
wydajność graficzna. Rozwiązaniem tego problemu byłoby wprowadzenie mechanizmu przekazywania kontroli nad kartą graficzną
systemowi gościa maszyny wirtualnej. Aby takie podejście było możliwe w przypadku posiadania tylko jednej karty graficznej,
wymagane byłoby jej wcześniejsze odpięcie od systemu zarządcy. Istnieje kilka projektów\cite{bib:joe-knock-git}, które wykorzystują mechanizm
,,zaczepów'' (ang. hooks) do odłączania urządzeń PCI przy uruchamianiu maszyny wirtualnej i podpinania ich z powrotem do systemu
zarządcy po wyłączeniu maszyny wirtualnej. Jednak to rozwiązanie wymaga skomplikowanej konfiguracji na maszynach klienckich,
między innymi wybrania odpowiednich urządzeń PCI do przekazania do maszyny wirtualnej, gdzie adresy tych urządzeń będą różne
na każdej z maszyn, a także ta konfiguracja byłaby różna dla każdego typu urządzeń. Napisanie programu, który w dynamiczny sposób
tworzyłby odpowiednie pliki konfiguracyjne, byłoby na pewno skomplikowane, ale możliwe.
\paragraph{}
Potencjalnym kierunkiem rozwoju tej aplikacji byłoby przeprojektowanie metody synchronizacji obrazów. Optymalną opcją wydaje się
użycie narzędzia rsync, aby zapewnić inkrementalne aktualizacje obrazów, bez potrzeby pobierania całości. Sporym ułatwieniem
pracy dla administratora byłoby także przygotowanie graficznego interfejsu użytkownika do zarządzania serwerem.
Po stronie klienta
dobrym torem rozwoju byłoby opracowanie metody na przekazywanie kontroli nad kartą graficzną systemowi gościa w sposób w pełni
zautomatyzowany. Ważnym krokiem byłoby także dopracowanie interfejsu użytkownika.
\paragraph{}
Powyżej przedstawione propozycje rozwoju są tylko sugestią, ponieważ architektura aplikacji pozwala na łatwą integrację z innymi
rozwiązaniami automatyzującymi. Dzięki temu przedstawiony projekt jest silnie rozwojowy, a przez użycie rozwiązań na licencjach
Wolnego Oprogramowania możliwe jest wykorzystanie go w placówkach naukowych bardzo niskim kosztem.
\backmatter
\backmatter
@ -1456,28 +1735,42 @@ W ramach trzeciej fazy testów, poddano ocenie wydajność i odczucia płynące
\chapter{Spis skrótów i symboli}
\chapter{Spis skrótów i symboli}
\begin{itemize}
\begin{itemize}
\item[DNA] kwas deoksyrybonukleinowy (ang. \ang{deoxyribonucleic acid})
\item[SFTP] Protokół Bezpiecznego Przesyłu Plików (ang. \ang{Secure File Transfer Protocol})
\item[MVC] model -- widok -- kontroler (ang. \ang{model--view--controller})
\item[SSH] Bezpieczna Powłoka (ang. \ang{Secure SHell})
\item[$N$] liczebność zbioru danych
\item[HTTP] Protokół Przesyłu HiperTekstu (ang. \ang{HyperText Transfer Protocol})
\item[$\mu$] stopnień przyleżności do zbioru
\item[WWW] OgólnoŚwiatowa Sieć (ang. \ang{World Wide Web})
\item[$\mathbb{E}$] zbiór krawędzi grafu
\item[CERN] Europejska Organizacja Badań Jądrowych (fr. \ang{Organisation Européenne pour la Recherche Nucléaire})
\item[$\mathcal{L}$] transformata Laplace'a
\item[TCP] Protokół Sterowania Transmisją (ang. \ang{Transmission Control Protocol})
\item[KVM] Maszyna Wirtualna Jądra (ang. \ang{Kernel Virtual Machine})
\item[MMU] Jednostka Zarządzająca Pamięcią (ang. \ang{Memory Management Unit})
\item[IOMMU] Jednostka Zarządzająca Pamięcią Wejścia Wyjścia (ang. \ang{Input Output Memory Management Unit})
\item[DHCP] Protokół Dynamicznego Konfigurowania Hostów (ang. \ang{Dynamic Host Configuration Protocol})
\item[BOOTP] Protokół Bootstrap (ang. \ang{BOOTstrap Protocol})
\item[TFTP] Trywialny Protokół Przesyłu Plików (ang. \ang{Trivial File Transfer Protocol})
\item[PXE] Przeduruchomieniowe Środowisko Uruchomieniowe (ang. \ang{Preboot Execution Environment})
\item[WOL] Uruchom Poprzez LAN (ang. \ang{Wake On LAN})
\item[WISM] ang. \ang{WindowsSystem Image Manager}
\item[DISM] ang. \ang{Deployment Image Servicing and Management}
\item[AD] ang. \ang{Active Directory}
\item[JWT] ang. \ang{JSON Web Token}
\item[JSON] Notacja Obiektów JavaScript (ang. \ang{JavaScript Object Notation})
\item[ORM] Mapowanie obiektowo-relacyjne (ang. \ang{Object-Relational Mapping})
\end{itemize}
\end{itemize}
% TODO
% TODO
\chapter{Źródła}
%\chapter{Źródła}
%
Jeżeli w pracy konieczne jest umieszczenie długich fragmentów kodu źródłowego, należy je przenieść w to miejsce.
%Jeżeli w pracy konieczne jest umieszczenie długich fragmentów kodu źródłowego, należy je przenieść w to miejsce.
%
\begin{lstlisting}
%\begin{lstlisting}
if (_nClusters < 1)
%if (_nClusters < 1)
throw std::string ("unknown number of clusters");
% throw std::string ("unknown number of clusters");
if (_nIterations < 1 and _epsilon < 0)
%if (_nIterations < 1 and _epsilon < 0)
throw std::string ("You should set a maximal number of iteration or minimal difference -- epsilon.");
% throw std::string ("You should set a maximal number of iteration or minimal difference -- epsilon.");
if (_nIterations > 0 and _epsilon > 0)
%if (_nIterations > 0 and _epsilon > 0)
throw std::string ("Both number of iterations and minimal epsilon set -- you should set either number of iterations or minimal epsilon.");
% throw std::string ("Both number of iterations and minimal epsilon set -- you should set either number of iterations or minimal epsilon.");
\end{lstlisting}
%\end{lstlisting}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -1503,10 +1796,8 @@ if (_nIterations > 0 and _epsilon > 0)
W systemie do pracy dołączono dodatkowe pliki zawierające:
W systemie do pracy dołączono dodatkowe pliki zawierające:
\begin{itemize}
\begin{itemize}
\item źródła programu,
\item źródła programów oraz pliki konfiguracyjne i skrypty
\item dane testowe,
\item film pokazujący działanie opracowanego oprogramowania
\item film pokazujący działanie opracowanego oprogramowania lub zaprojektowanego i~wykonanego urządzenia,