diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..c3427a3 Binary files /dev/null and b/.DS_Store differ diff --git a/main.pdf b/main.pdf index 4988a1c..28ab09c 100644 Binary files a/main.pdf and b/main.pdf differ diff --git a/main.tex b/main.tex index 1b87569..a439115 100644 --- a/main.tex +++ b/main.tex @@ -822,45 +822,253 @@ oprogramowania na maszynie zarządzanej, wystarczy jedynie uruchomiony serwer SS % TODO -\chapter{Wymagania i narzędzia (WORK IN PROGRESS)} +\chapter{Wymagania i narzędzia} \label{ch:wymagania-i-narzedzia} +\paragraph{Wymagania funkcjonalne} +Rozwiązanie powinno spełniać następujące wymagania funkcjonalne: + +\begin{itemize} + \item pełna automatyzacja procesu instalowania i konfiguracji systemu operacyjnego na urządzeniach + \item użycie maszyn wirtualnych + \item pozorna ,,bezstanowość'': po zakończeniu pracy w maszynie wirtualnej i jej wyłączeniu, kolejne jej uruchomienie przywróci pierwotny obraz dysku maszyny, bez zmian wprowadzonych przez poprzedniego użytkownika + \item proste tworzenie obrazów maszyn wirtualnych o zmodyfikowanej konfiguracji + \item łatwość użycia: użytkownicy końcowi powinni być w stanie w łatwy sposób obsługiwać maszyny klienckie +\end{itemize} + +\paragraph{Wymagania niefunkcjonalne} +Rozwiązanie powinno spełniać następujące wymagania niefunkcjonalne: + +\begin{itemize} + \item modularność: możliwość łatwego dodania nowych funkcjonalności + \item użycie rozwiązań, które są Wolnym Oprogramowaniem + \item możliwość wbudowania rozwiązania w już istniejącą architekturę sieciową +\end{itemize} + +\paragraph{} +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 +cloud-init do automatycznego przeprowadzenia procesu instalacji systemu operacyjnego nadzorcy oraz narzędzie Ansible, do pełnej +konfiguracji systemu operacyjnego zarządcy. + \paragraph{} -Do implementacji pierwszej części projektu wyszczególnionej powyżej wykorzystano język Python, do zaimplementowania prostego serwera oraz klienta, synchronizujących -obrazy maszyn wirtualnych, QEMU wraz z KVM do uruchamiania samych maszyn oraz system operacyjny nadzorcy Ubuntu Linux w wersji 22.04 LTS. +Całość rozwiązania instalacyjno-konfiguracyjnego zaimplementowano pod kontrolą systemu operacyjnego Ubuntu Linux w +wersji 22.04 LTS na urządzeniu Dell Wyse 5060. Jest to tak zwany ,,cienki klient'', czyli zminiaturyzowana wersja komputera +osobistego o ograniczonej mocy obliczeniowej, której celem było uruchamianie klienta zdalnego pulpitu i umożliwienie w ten sposób +pracy na dużo wydajniejszej maszynie. Maszyny te są obecnie często wykorzystywane przez pasjonatów jako energooszczędne +alternatywy dla komputerów jednopłytkowych (takich jak Raspberry Pi) i służą jako prywatne serwery domowe. Wykorzystany +terminal posiada czterordzeniowy procesor AMD GX-424CC, 8 GB pamięci RAM, dysk SATA SSD 256GB oraz gigabitową kartę sieciową +opartą o chip Realtek RTL8111/8168/8411. \paragraph{} -Część projektu odpowiedzialna za obsługę systemów zarządców maszyn wirtualnych została także oparta o system operacyjny Ubuntu Linux w wersji 22.04 LTS, -serwer TFTP oraz PXE do serwowania medium instalacyjnego systemu bazowego nadzorców, cloud-init oraz Ansible do automatyzacji instalacji i konfiguracji hostów. +Do obsługi wirtualizacji wykorzystano narzędzie QEMU. Jest to zintegrowany system do emulacji procesorów poprzez tłumaczenie binarne, potrafi także korzystać z technologii KVM do uruchamiania +aplikacji/maszyn wirtualnych z minimalnym narzutem wydajnościowym.\cite{bib:qemu-main} W proponowanym +rozwiązaniu użyto trybu, gdzie QEMU korzysta z KVM, aby zapewnić jak najlepszą wydajność. + + +% \begin{itemize} +% \item wymagania funkcjonalne i niefunkcjonalne +% \item przypadki użycia (diagramy UML) -- dla prac, w których mają zastosowanie +% \item opis narzędzi, metod eksperymentalnych, metod modelowania itp. +% \item metodyka pracy nad projektowaniem i implementacją -- dla prac, w których ma to zastosowanie +% \end{itemize} + + +% TODO +\chapter{Specyfikacja zewnętrzna} +\label{ch:specyfikacja-zewnetrzna} + +\paragraph{Wymagania sprzętowe - strona kliencka} +Maszyny klienckie, na których uruchomiona ma być aplikacja kliencka i maszyny wirtualne, powinny spełniać następujące wymagania: -\paragraph{QEMU} -QEMU to zintegrowany system do emulacji procesorów poprzez tłumaczenie binarne, potrafi także korzystać z technologii KVM do uruchamiania -aplikacji/maszyn wirtualnych z minimalnym narzutem wydajnościowym. \cite{bib:qemu-main} \begin{itemize} -\item wymagania funkcjonalne i niefunkcjonalne -\item przypadki użycia (diagramy UML) -- dla prac, w których mają zastosowanie -\item opis narzędzi, metod eksperymentalnych, metod modelowania itp. -\item metodyka pracy nad projektowaniem i implementacją -- dla prac, w których ma to zastosowanie + \item procesor 64-bit, wspierający Intel VT-d, lub AMD-V + \item program uruchomieniowy UEFI + \item co najmniej 4GB pamięci RAM, preferowane 8GB + \item dysk o pojemności co najmniej 250GB + \item płyta główna wspierająca Wake On LAN oraz uruchamianie poprzez PXE + \item karta graficzna o wydajności zbliżonej do Intel HD Graphics 620, na przykład APU z serii AMD Ryzen, Nvidia GT 1030, lub nawet Nvidia GT 730 + \item karta sieciowa wspierająca Wake On LAN i prędkości 1 gigabit \end{itemize} +\paragraph{Wymagania sprzętowe - strona sieciowa} +Sieć, w której ma operować projekt, powinna spełniać poniższe warunki: -% TODO -\chapter{[Właściwy dla kierunku -- np. Specyfikacja zewnętrzna]} -\label{ch:04} +\begin{itemize} + \item warstwa łącza zbudowana w oparciu o sieć Ethernet w klasie co najmniej 5E (osiągającą prędkości 1 gigabita) + \item urządzenia sieciowe pozwalające na transmisję ,,magic packet'' + \item preferencyjnie dedykowana podsieć, wyłącznie dla zarządzanych maszyn klienckich +\end{itemize} + +\paragraph{Wymagania sprzętowe - strona serwera} +Serwer, na którym uruchomione będą aplikacje serwerów, powinien spełniać następujące wymagania: -Jeśli „Specyfikacja zewnętrzna”: \begin{itemize} -\item wymagania sprzętowe i programowe -\item sposób instalacji -\item sposób aktywacji -\item kategorie użytkowników -\item sposób obsługi -\item administracja systemem -\item kwestie bezpieczeństwa -\item przykład działania -\item scenariusze korzystania z systemu (ilustrowane zrzutami z ekranu lub generowanymi dokumentami) + \item co najmniej gigabitowa karta sieciowa + \item procesor czterordzeniowy + \item 8GB pamięci RAM, 8GB pamięci SWAP + \item dysk o pojemności co najmniej 250GB \end{itemize} +\paragraph{Sposób instalacji} +Procedura instalacji serwera zarządcy obrazów i maszyn jest następująca: + +\begin{itemize} + \item system operacyjny, na którym uruchamiany jest serwer powinien posiadać zainstalowane następujące pakiety: + \begin{itemize} + \item serwer HTTP Apache2 (apache2 dla Ubuntu) + \item implementację ISC serwera DHCP (dhcp-isc-server dla Ubuntu) + \item serwer TFTP (tftp-hpa dla Ubuntu) + \item interpreter Python w wersji co najmniej 3.9 + \end{itemize} + \item po instalacji wymaganych pakietów należy utworzyć wymagane katalogi: + \begin{itemize} + \item \texttt{/ks} - katalog zawierający pliki konfiguracyjne dla narzędzia cloud-init + \item \texttt{/images} - katalog zawierający obraz systemu operacyjnego zarządcy dla maszyn klienckich (Ubuntu Server 22.04 LTS) + \item \texttt{/srv/tftp} - katalog zawierający pliki do uruchomienia instalatora poprzez PXE + \end{itemize} + \item skopiować pliki konfiguracyjne z repozytorium poniżej do odpowiednich katalogów + + \texttt{https://git.nixenos.ovh/engineering-degree/configuration-files.git} + \item przygotować listę adresów MAC zarządzanych urządzeń + \item skonfigurować serwer DHCP tak, aby przypisywał stałe adresy IP urządzeniom klienckim, spisać te adresy + \item do katalogu należy pobrać kod źródłowy aplikacji serwera: + + \texttt{git clone https://git.nixenos.ovh/engineering-degree/orchestrator-app.git} + \item następnie należy przejść do katalogu zawirającego aplikację \texttt{cd orchestrator-app} + \item utworzyć środowisko wirtualne Python i uruchomić je: + \begin{itemize} + \item \texttt{python3 -m venv .env} + \item \texttt{source .env/bin/activate} + \end{itemize} + \item skonfigurować opcje serwera w pliku konfiguracyjnym \texttt{config.yml} + \item zresetować serwer dhcp, tftp oraz http + \item uruchomić serwer obrazów komendą \texttt{python fleetcontrol run} + \item pobrać zestaw skryptów Ansible + + \texttt{git clone https://git.nixenos.ovh/engineering-degree/ansible-scripts.git} + \item uzupełnić plik inventory/nodes.yml adresami IP przypisanymi do urządzeń klienckich w konfiguracji serwera DHCP +\end{itemize} + +\paragraph{} +Proces instalacji i konfiguracji klientów jest następujący: + +\begin{itemize} + \item uruchomić wspracie dla PXE oraz Wake On LAN w oprogramowaniu BIOS + \item ustawić PXE jako pierwsze urządzenie uruchomieniowe, jako drugie ustawić lokalny dysk twardy + \item wysłać do każdego urządzenia ,,magic packet'': + + \texttt{wakeonlan -i adres-broadcast-sieci adres-mac-urządzenia} + \item uruchomić instalator klikając enter w oknie wyboru przedstawionym na rys. \ref{fig:boot-screen-pxe} + \item po restarcie wszystkich urządzeń, podmienić adres IP serwera w pliku config.yml i uruchomić skrypty ansible z katalogu \texttt{ansible-scripts} na serwerze: + + \texttt{ansible-playbook provision-new-node.yml -i inventory/nodes.yml -K} +\end{itemize} + +\begin{figure}[hb] + \centering + \includegraphics[width=\textwidth]{./pictures/boot-screen-pxe.png} + \caption{Ekran wyboru systemu do zainstalowania} + \label{fig:boot-screen-pxe} +\end{figure} + +\paragraph{Obsługa - strona serwera} +Po wykonaniu wstępnej konfiguracji, należy zbudować obraz maszyny wirtualnej i zarejestrować go w systemie ich obsługi. +Aby zbudować obraz maszyny wirtualnej, wystarczy stworzyć obraz dysku w formacie qcow2 (np. \texttt{qemu-img create -f qcow2 ubuntu.qcow2 20G}), +a następnie uruchomić maszynę wirtualną z tym obrazem dysku i medium instalacyjnym, zainstalować oraz skonfigurować system operacyjny, +a następnie skopiować utworzony obraz dysku na serwer. + +Będąc zalogowanym do powłoki na serwerze, należy umieścić obraz dysku w miejscu, gdzie użytkownik uruchamiający serwer ma dostęp do odczytu i zapisu plików. +Następnie, należy zarejestrować obraz w bazie danych serwera komendą \texttt{python fleetcontrol add\_image}, przykład użycia +przedstawiono na rys. \ref{fig:register-image-command}. Po dodaniu obrazu można zweryfikować, że obraz został prawidłowo zarejestrowany +poprzez komendę \texttt{python fleetcontrol print\_images}. Dla skonfigurowanego serwera dała ona rezultat przedstawiony na rys. \ref{fig:print-images-command}. + +Po pierwszym uruchomieniu wszystkie maszyny klienckie powinny same się zarejestrować na serwerze, co można sprawdzić komendą +\texttt{python fleetcontrol print\_clients}. Przykładowy rezultat takiej komendy predstawiono na rys. \ref{fig:print-clients-command}. + +Po pomyślnej weryfikacji, można przypisać obrazy do klientów. Odbywa sie to poprzez komendę +\texttt{python fleetcontrol assign\_image} zaprezentowaną na rys. \ref{fig:assign-image-command}. + +Konfiguracja serwera odbywa się poprzez edycję pliku \texttt{config.yml}, lub poprzez ustawienie następujących zmiennych środowiskowych +przed uruchomieniem serwera: + +\begin{itemize} + \item \texttt{VALHALLA\_SERVER\_NAME} - nazwa serwera + \item \texttt{VALHALLA\_SERVER\_PORT} - port na którym ma nasłuchiwać serwer + \item \texttt{VALHALLA\_SERVER\_HOST} - adres IP hosta, na którym działa serwer (adres karty sieciowej wpiętej do sieci, w której są maszyny klienckie) + \item \texttt{VALHALLA\_SERVER\_PASSWORD} - hasło dostępu do serwera dla klientów + \item \texttt{VALHALLA\_SERVER\_ACCESS\_USERNAME} - nazwa użytkownika dostępowego dla klientów + \item \texttt{VALHALLA\_JWT\_SECRET} - sekretna fraza wykorzystywana do obliczenia tokenu JWT + \item \texttt{VALHALLA\_DATABASE\_FILE} - inny plik bazy danych SQLite3 + \item \texttt{VALHALLA\_LOGLEVEL} - poziom logowania dla aplikacji serwera +\end{itemize} + +Każde z tych ustawień można ustawić także poprzez plik config.yml, jednak to zmienne środowiskowe mają pierwszeństwo i są +brane pod uwagę preferencyjnie. Po zmianie ustawień serwera należy pamiętać o aktualizacji ustawień klienta. Odbywa się to +poprzez edycję pliku \texttt{config.yml} w katalogu \texttt{ansible\_scripts}. + +\begin{figure}[hb] + \centering + \includegraphics[width=\textwidth]{./pictures/add_image_command.png} + \caption{Przykład rejestrowania obrazu maszyny wirtualnej} + \label{fig:register-image-command} +\end{figure} + +\begin{figure}[hb] + \centering + \includegraphics[width=\textwidth]{./pictures/print_images_command.png} + \caption{Przykładowy wynik komendy wyświetlającej wszystkie zarejestrowane obrazy} + \label{fig:print-images-command} +\end{figure} + +\begin{figure}[hb] + \centering + \includegraphics[width=\textwidth]{./pictures/print_clients_command.png} + \caption{Przykładowy wynik komendy wyświetlającej wszystkich zarejestrowanych klientów} + \label{fig:print-clients-command} +\end{figure} + +\begin{figure}[hb] + \centering + \includegraphics[width=\textwidth]{./pictures/assign_image_command.png} + \caption{Przykładowe wywołanie komendy przypisującej obraz do klienta} + \label{fig:assign-image-command} +\end{figure} + +\paragraph{Obsługa - strona klienta} +Maszyna kliencka po uruchomieniu przedstawia ekran wyboru obrazu maszyny wirtualnej do uruchomienia, zaprezentowany na rys. \ref{fig:client-runner-screen}. +Użytkownik wybiera interesujący go obraz korzystając ze strzałek, następnie klawiszem tabulatora wybiera opcję OK i naciska klawisz Enter. +Wtedy cały ekran przejmowany jest przez maszynę wirtualną, która uruchamia się. Po skończonej pracy w maszynie wirtualnej i jej wyłączeniu, +znów pojawia się ekran wyboru obrazu maszyny. + +\begin{figure}[hb] + \centering + \includegraphics[width=\textwidth]{./pictures/screenshot-client-app-running.png} + \caption{Ekran wyboru maszyny wirtualnej do uruchomienia} + \label{fig:client-runner-screen} +\end{figure} + +\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 +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. +Nie posiada ona jednak aplikacji klienckiej, ani żadnej konfiguracji, jedynie klucz publiczny SSH, wymagany do wykonania +skryptów Ansible. Jednak o ile złośliwy aktor nie podszyje się pod adres IP dowolnej maszyny do skonfigurowania, nie zostana na takiej maszynie +wykonane skrypty konfigurujące aplikację kliencką oraz nie zostaną przekazane pliki konfiguracyjne. + +% Jeśli „Specyfikacja zewnętrzna”: +% \begin{itemize} +% \item wymagania sprzętowe i programowe +% \item sposób instalacji +% \item sposób aktywacji +% \item kategorie użytkowników +% \item sposób obsługi +% \item administracja systemem +% \item kwestie bezpieczeństwa +% \item przykład działania +% \item scenariusze korzystania z systemu (ilustrowane zrzutami z ekranu lub generowanymi dokumentami) +% \end{itemize} + %%%%%%%%%%%%%%%%%%%%% %% RYSUNEK Z PLIKU % @@ -910,99 +1118,262 @@ Jeśli „Specyfikacja zewnętrzna”: -\begin{figure} -\centering -\begin{tikzpicture} -\begin{axis}[ - y tick label style={ - /pgf/number format/.cd, - fixed, % po zakomentowaniu os rzednych jest indeksowana wykladniczo - fixed zerofill, % 1.0 zamiast 1 - precision=1, - /tikz/.cd - }, - x tick label style={ - /pgf/number format/.cd, - fixed, - fixed zerofill, - precision=2, - /tikz/.cd - } -] -\addplot [domain=0.0:0.1] {rnd}; -\end{axis} -\end{tikzpicture} -\caption{Podpis rysunku po rysunkiem.} -\label{fig:2} -\end{figure} +% \begin{figure} +% \centering +% \begin{tikzpicture} +% \begin{axis}[ +% y tick label style={ +% /pgf/number format/.cd, +% fixed, % po zakomentowaniu os rzednych jest indeksowana wykladniczo +% fixed zerofill, % 1.0 zamiast 1 +% precision=1, +% /tikz/.cd +% }, +% x tick label style={ +% /pgf/number format/.cd, +% fixed, +% fixed zerofill, +% precision=2, +% /tikz/.cd +% } +% ] +% \addplot [domain=0.0:0.1] {rnd}; +% \end{axis} +% \end{tikzpicture} +% \caption{Podpis rysunku po rysunkiem.} +% \label{fig:2} +% \end{figure} % TODO -\chapter{[Właściwy dla kierunku -- np. Specyfikacja wewnętrzna]} -\label{ch:05} +\chapter{Specyfikacja wewnętrzna} +\label{ch:specyfikacja-wewnetrzna} +\paragraph{Idea rozwiązania} +Zamysł proponowanego rozwiązania jest dość prosty i opiera się na kilku elementach: -Jeśli „Specyfikacja wewnętrzna”: \begin{itemize} -\item przedstawienie idei -\item architektura systemu -\item opis struktur danych (i organizacji baz danych) -\item komponenty, moduły, biblioteki, przegląd ważniejszych klas (jeśli występują) -\item przegląd ważniejszych algorytmów (jeśli występują) -\item szczegóły implementacji wybranych fragmentów, zastosowane wzorce projektowe -\item diagramy UML + \item serwer przechowuje metadane o obrazach (nazwa, wersja, hash pliku, lokalizacja pliku), same pliki obrazów oraz dane o klientach (nazwa hosta, adres IP, adres MAC, wersja aplikacji klienckiej) + \item dane o obrazach jak i same obrazy są ręcznie dodawane przez administratora + \item klienci sami rejestrują się oraz aktualizują dane o sobie na serwerze + \item klienci pobierają dane o przypisanych do siebie maszynach wirtualnych, pobierają także przypisane obrazy + \item komunikacja odbywa się poprzez protokół HTTP + \item do komunikacji z serwerem wymagana jest autoryzacja poprzez token JWT(JSON Web Token), uzyskiwany poprzez wysłanie loginu oraz hasła w formacie JSON do odpowiedniego punktu końcowego na serwerze + \item po synchronizacji stanu pomiędzy klientem a serwerem, na kliencie uruchamia się okno wyboru obrazu do uruchomienia + \item aplikacja klienta zbiera także podstawowe dane o maszynie: (zainstalowaną pojemność pamięci RAM, liczbę wątków procesora, adres IP oraz MAC karty sieciowej, która ma połączenie z siecią) + \item po wybraniu obrazu, na podstawie danych o maszynie zebranych przez aplikację klienta generowany jest skrypt, uruchamiający program QEMU z zebranymi danymi jako argumentami wywołania + \item oryginalny obraz maszyny wirtualnej jest kopiowany, a następnie uruchamiany jest skrypt włączający maszynę wirtualną + \item po zakończonej pracy i wyłączeniu maszyny wirtualnej, skrypt podmienia modyfikowany obraz dysku maszyny wirtualnej na oryginalny, skopiowany w kroku wcześniej + \item środowisko klienta składa się z bardzo okrojonego środowiska graficznego \texttt{i3}\footnote{\url{https://i3wm.org/}}, które nie pozwala na wyjście z aplikacji klienckiej oraz emulatora terminala rxvt + \item po uruchomieniu maszyny wirtualnej środowisko graficzne promuje jej okno do wypełnienia całego ekranu, jednocześnie przechwytując klawiaturę i myszkę, aby przekierować je do obsługi maszyny wirtualnej \end{itemize} -% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % -% Pakiet minted wymaga odkomentowania w pliku config/settings.tex % -% importu pakietu minted: \usepackage{minted} % -% i specjalnego kompilowania: % -% pdflatex -shell-escape praca % -% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % +\paragraph{Architektura sieciowa rozwiązania} +Proponowana architektura sieciowa dla rozwiązania została zaprezentowana na rys. \ref{fig:prop-network}. +Zakłada ona, że serwer DHCP będzie na tej samej maszynie co serwer TFTP oraz zarządcy obrazów, jednak +możliwe jest rozbicie każdego z tych narzędzi na osobną maszynę dedykowaną. Podobnie, jeżeli zagwarantowana +zostanie poprawna konfiguracja, możliwe jest wykorzystanie dowolnego serwera DHCP, jednak przetestowana została +wyłącznie architektura z serwerem DHCP w implementacji ISC. +\begin{figure}[hb] + \centering + \includegraphics[width=\textwidth]{./pictures/architektura-pracy-inzynierskiej-sieciowa.png} + \caption{Proponowana architektura sieciowa dla rozwiązania} + \label{fig:prop-network} +\end{figure} -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} -, a naprawdę długie fragmenty – w załączniku. +\paragraph{Strona serwera} +Logika serwera zarządcy obrazów opiera się na koncepcie obrazu oraz klienta. Istnieje tylko jeden użytkownik, wspólny dla wszystkich +klientów. Każdy klient może mieć przypisane do siebie wiele obrazów. Diagram klas wykorzystywanych przez aplikację przedstawiono +na rys. \ref{fig:class-diagram-server}. +\begin{figure}[hb] + \centering + \includegraphics[width=\textwidth]{./pictures/diagram_klaspng.png} + \caption{Diagram klas wykorzystywanych przez serwer} + \label{fig:class-diagram-server} +\end{figure} -\begin{figure} -\centering -\begin{lstlisting} -class test : public basic -{ - public: - test (int a); - friend std::ostream operator<<(std::ostream & s, - const test & t); - protected: - int _a; - -}; -\end{lstlisting} -\caption{Pseudokod w \texttt{listings}.} -\label{fig:pseudokod:listings} +\paragraph{} +Dane o obrazach i klientach przechowywane są w bazie danych SQLite3. Aplikacja korzysta z biblioteki ORM (Object-Relational Mapping) +SQLAlchemy dla języka Python. Narzędzie to stworzyło 4 tabele o następujących kolumnach: + +\begin{itemize} + \item clients: + \begin{itemize} + \item mac\_address: VARCHAR NOT NULL PRIMARY KEY + \item ip\_address: VARCHAR(16) NOT NULL + \item hostname: VARCHAR(100) NOT NULL + \item client\_version: VARCHAR(100) NOT NULL + \end{itemize} + \item vm\_images: + \begin{itemize} + \item image\_id: INTEGER NOT NULL PRIMARY KEY + \item image\_name: VARCHAR(100) NOT NULL + \item image\_file: VARCHAR(500) NOT NULL + \item image\_version: VARCHAR(100) NOT NULL + \item image\_hash: VARCHAR(500) NOT NULL + \item image\_name\_version\_combo: VARCHAR (600) NOT NULL + \end{itemize} + \item users: + \begin{itemize} + \item user\_id: INTEGER NOT NULL PRIMARY KEY + \item username: VARCHAR NOT NULL + \item password\_hash: VARCHAR NOT NULL + \end{itemize} + \item client\_image: + \begin{itemize} + \item client\_mac: FOREIGN KEY VARCHAR + \item mage\_id: FOREIGN KEY INTEGER + \end{itemize} +\end{itemize} + +\paragraph{} +Do stworzenia serwera wykorzystano następujące biblioteki: + +\begin{itemize} + \item bcrypt - do tworzenia bezpiecznych ,,hashy'' (wyników funkcji skrótu) haseł + \item Flask - do stworzenia serwera HTTP + \item pyaml - do odczytu i analizy plików o rozszerzeniu YAML + \item PyJWT - do obsługi i tworzenia tokenów JWT + \item prettytable - do formatowania danych w przejrzysty sposób + \item SQLAlchemy - jako ORM do obsługi bazy danych + \item argparse - do parsowania argumentów wywołania programu +\end{itemize} + +\paragraph{} +Program został podzielony na kilka głównych modułów: + +\begin{itemize} + \item obsługa bazy danych + \item serwer HTTP, obsługa żądań i odpowiedzi + \item obsługa pliku konfiguracyjnego i zmiennych środowiskowych + \item moduł modeli danych dla bazy danych + \item moduł obsługi autoryzacji poprzez tokeny JWT +\end{itemize} + +\paragraph{} +Obsługa bazy danych została zaimplementowana w klasie \texttt{Database}. Jej zadaniem jest zestawienie połączenia z bazą danych +oraz manipulacja wszystkimi modelami wykorzystywanymi w programie. Dodawanie, usuwanie, modyfikacja i pobieranie danych +z bazy danych odbywa się poprzez zaimplementowane metody. Są one wysokopoziomowymi abstrakcjami podstawowych zapytań +SQL: + +\begin{itemize} + \item metody o formacie \texttt{get\_[nazwa\_modelu]\_by\_[nazwa\_atrybutu]} odpowiadają zapytaniom \texttt{SELECT} + \item metody o formacie \texttt{add\_[nazwa\_modelu]} odpowiadają zapytaniom \texttt{INSERT} + \item metody o formacie \texttt{modify\_[nazwa\_modelu]} odpowiadają zapytaniom \texttt{UPDATE} + \item metody o formacie \texttt{delete\_[nazwa\_modelu]} odpowiadają zapytaniom \texttt{DELETE} +\end{itemize} + +\paragraph{} +Serwer HTPP został zbudowany w oparciu o bibliotekę Flask. Do obsługi zapytań HTTP stworzono klasę \texttt{Server}, która +zawiera w sobie metody, które obsługują wszystkie punkty końcowe. Autoryzacja dostępu została zaimplementowana przez mechanizm +dekoratorów, a dokładniej przez zaimplementowany dekorator \texttt{require\_auth}. Sprawdza on, czy w nagłówkach zapytania HTTP +klient wysłał odpowiedni token JWT i jeżeli nie był poprawny, zwraca odpowiedni komunikat do klienta. Jeżeli jednak był poprawny, +przekazuje do funkcji obsługującej zapytanie informacje o zautoryzowanym użytkowniku. Przykład użycia tego dekoratora przedstawiono +na listingu \ref{fig:requireauth:listings}. + +\begin{figure}[hb] + \centering + \begin{lstlisting} +class Server: + @require_auth + def register_new_client_to_database(request_user, self): + \end{lstlisting} + \caption{Przykład użycia dekoratora \texttt{require\_auth}} + \label{fig:requireauth:listings} \end{figure} -%\begin{figure} -%\centering -%\begin{minted}[linenos,frame=lines]{c++} -%class test : public basic -%{ -% public: -% test (int a); -% friend std::ostream operator<<(std::ostream & s, -% const test & t); -% protected: -% int _a; -% -%}; -%\end{minted} -%\caption{Pseudokod w \texttt{minted}.} -%\label{fig:pseudokod:minted} -%\end{figure} +\paragraph{} +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. +Do obsługi plików konfiguracyjnych wybrano bibliotekę \texttt{PYAML}. + +\paragraph{Strona klienta} +Po stronie klienta jedyną strukturą danych jaka została wykorzystana, był model obrazu, wykorzystywany także po stronie serwera. +Wykorzystano następujące biblioteki: + +\begin{itemize} + \item picotui - do stworzenia interfejsu użytkownika + \item getmac - do pobrania informacji o karcie sieciowej + \item pyaml - do odczytu i parsowania plików konfiguracyjnych + \item requests - do wysyłania zapytań do serwera + \item psutil - do pobierania informacji o dostępnej liczbie rdzeni i pamięci operacyjnej urządzenia +\end{itemize} + +\paragraph{} +Aplikacja klienta została podzielona na klika podstawowych modułów: + +\begin{itemize} + \item moduł sprawdzający dane o maszynie, na której jest uruchomiony + \item moduł obsługujący komunikację z serwerem + \item moduł obsługujący uruchamianie maszyn wirtualnych oraz wyświetlanie interfejsu użytkownika +\end{itemize} + +\paragraph{} + + +% Jeśli „Specyfikacja wewnętrzna”: +% \begin{itemize} +% \item przedstawienie idei +% \item architektura systemu +% \item opis struktur danych (i organizacji baz danych) +% \item komponenty, moduły, biblioteki, przegląd ważniejszych klas (jeśli występują) +% \item przegląd ważniejszych algorytmów (jeśli występują) +% \item szczegóły implementacji wybranych fragmentów, zastosowane wzorce projektowe +% \item diagramy UML +% \end{itemize} +% +% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % +% % 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} +% , a naprawdę długie fragmenty – w załączniku. +% +% +% \begin{figure} +% \centering +% \begin{lstlisting} +% class test : public basic +% { +% public: +% test (int a); +% friend std::ostream operator<<(std::ostream & s, +% const test & t); +% protected: +% int _a; +% +% }; +% \end{lstlisting} +% \caption{Pseudokod w \texttt{listings}.} +% \label{fig:pseudokod:listings} +% \end{figure} +% +% %\begin{figure} +% %\centering +% %\begin{minted}[linenos,frame=lines]{c++} +% %class test : public basic +% %{ +% % public: +% % test (int a); +% % friend std::ostream operator<<(std::ostream & s, +% % const test & t); +% % protected: +% % int _a; +% % +% %}; +% %\end{minted} +% %\caption{Pseudokod w \texttt{minted}.} +% %\label{fig:pseudokod:minted} +% %\end{figure} @@ -1010,6 +1381,21 @@ class test : public basic % TODO \chapter{Weryfikacja i walidacja} \label{ch:06} + +\paragraph{Sposób testów} +Testy całości rozwiązania zostały przeprowadzone korzystając z komputera Lenovo Thinkpad T480. +Posiada procesor Intel Core i5-8250U (4 rdzenie, 8 wątków), 24GB pamięci RAM oraz dysk SSD o pojemności 256GB. +Pracuje pod kontrolą UEFI, wspiera Intel VT-d oraz PXE. + +W ramach pierwszej fazy testów urządzenie było wielokrotnie czyszczone oraz konfigurowane ponownie. W ich trakcie przeporwadzono +pomiary czasu jaki jest wymagany do pełnej konfiguracji maszyny. + +W ramach drugiej fazy testów ręcznie wymuszano proces synchronizacji zmian z serwerem. Do testów przygotowano obraz maszyny wirtualnej +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. + +W ramach trzeciej fazy testów, poddano ocenie wydajność i odczucia płynące z używania maszyny wirtualnej. + \begin{itemize} \item sposób testowania w ramach pracy (np. odniesienie do modelu V) \item organizacja eksperymentów diff --git a/pictures/.DS_Store b/pictures/.DS_Store new file mode 100644 index 0000000..43eab28 Binary files /dev/null and b/pictures/.DS_Store differ diff --git a/pictures/add_image_command.png b/pictures/add_image_command.png new file mode 100644 index 0000000..670b038 Binary files /dev/null and b/pictures/add_image_command.png differ diff --git a/pictures/architektura-pracy-inzynierskiej-sieciowa.png b/pictures/architektura-pracy-inzynierskiej-sieciowa.png new file mode 100644 index 0000000..c06dcfe Binary files /dev/null and b/pictures/architektura-pracy-inzynierskiej-sieciowa.png differ diff --git a/pictures/architektura-pracy-inzynierskiej-sieciowa.svg b/pictures/architektura-pracy-inzynierskiej-sieciowa.svg new file mode 100644 index 0000000..44b85dd --- /dev/null +++ b/pictures/architektura-pracy-inzynierskiej-sieciowa.svg @@ -0,0 +1,4 @@ + + + +
Serwer DHCP + TFTP + zarządcy obrazów
Serwer DHCP + TFTP + zarządcy ob...
Przełącznik sieciowy
Przełącznik sieciowy
Maszyny klienckie
Maszyny klienckie
Text is not SVG - cannot display
\ No newline at end of file diff --git a/pictures/assign_image_command.png b/pictures/assign_image_command.png new file mode 100644 index 0000000..573e0fa Binary files /dev/null and b/pictures/assign_image_command.png differ diff --git a/pictures/boot-screen-pxe.png b/pictures/boot-screen-pxe.png new file mode 100644 index 0000000..e0fb842 Binary files /dev/null and b/pictures/boot-screen-pxe.png differ diff --git a/pictures/diagram_klas.drawio b/pictures/diagram_klas.drawio new file mode 100644 index 0000000..d5ef453 --- /dev/null +++ b/pictures/diagram_klas.drawio @@ -0,0 +1 @@ +7Zpfc5s4EMA/jR97Y/DfPMZOcu1M0nbiuUnvXjwqkkFXoWWEHNv99F2BMGDAdS7BnvaYyWS8i4Sk3Z/E7kJvMA+3fyoSBQ9Amei5fbrtDW56rjueOvjfKHapYji4ShW+4jRVObliwb8zq+xb7ZpTFpcaagCheVRWeiAl83RJR5SCTbnZCkR51Ij4rKJYeERUtU+c6iDVTt1Jrn/PuB9kIztju76QZI3tSuKAUNgUVIPb3mCuAHT6K9zOmTC2y+yS9rtruLqfmGJSn9Jh8Wn38cPd1aend/9cUy6fZu7s8Z29yzMRa7vgueDmhumU9S6zQ7zhoSASpdkKpF7YK32UvYALek92sDbziDXxvmXSLADFv2N7IvCSgwq8rLR1s2t6r7gQcxCgUCEhGSDvtDA3s8MoFmO3z9l6nQPVA9mWGt6TWGcTBCFIFPOvyZRNx5Aon8sZaA2hbRTCM8kbJPcoyqCJLshIOSvKjPKiaGksazThkqnS1PfoGJV1BVOabRt97OzJwR3HIGRa7bCJ7TC0rO3K4iYn18l0QZFad2h3jN0t/v7O+8EezXqkjwt6wWiTmsEG/fJYRGimJNFsBmtJ4yLD+KOwylyVkP0Cyt0K5T13luxRb0koRV/gXK4T4BWXfgV+dIhO2FXwjR3AWsMvEdyXKAq2Mt2MRzmeKNdWrSEyN4uIh2PdJ21uhrnm0ZrKqAD7rkRyagScUiYPUDTgRsClTmw5muEfWnfe/2PUG+HE5yg7uYx/prnSc5C4FsTRjMNwo2yY2SynEdh8jlSxtGS4J3LojpsxLDHxUgAGDQDwqPP/Gfw/HF/Y/1cN/g8g1pKErPN+i96fuBf2/rDB+14S6ixxxTEH2TFwEKb0W2TianphJrL8ogDFh9DkAl3g+0sGvu5PY9F9FFKKfCdHAPsNIl+nmuDZyMfAvjR9zamH5wDz0UX/12PvFcdcv57L5si3lsP2zrmm3CcFoAt+2iagJvY9MwGNyU9CQBf9nAGCmhD4zBCMjkIQkDjoCGiTgJqA98wENGVBKQHoxO5B8MYZ0HEi9kXXyyEx/mlskD0elh6EX6EDpFUgRhcPFicVrzLqsyznRaME4IMk4jbXoqkxeWHUGjpvcw/GhUmC9y/TemdzX7LWYFJdHWaZMdty/aXw+29zK3RGKt1k2W0i7DJB4nq/FIVCLyPm3RIp70evzVtBFD1B4ph7qfKOi1KiXm2UqAvNUksZ8zRCYFUxrJXHjpjdBmg4gM+O8jOq50cxQTR/Lk/k7eGYVk6Ljy86BLId76GBzPFaWwHJsTg8EULc2wlwm4BrtsBzwIy5USSqQHjSFj1eUHCm5RR/Ut2b4xNS/LezfrWE/fD7Wn8wLlvfqcmjz2r+bPyC+Z/DpeCxXuLDMSRegCFD90j87x4/LKnVPQydsz4M3Wrp7K+4pkbWSoF43LBBL1EgfgPvHjj39A8T+kc+THidd5vqYmv0cVcXfXWs2wRERsCl3wi7TVUx4/+uKtq2/0fVgtiZ/d9UDokw4N+Aol1NrHUIJu29BEYx/7IyfZmWf546uP0B \ No newline at end of file diff --git a/pictures/diagram_klaspng.png b/pictures/diagram_klaspng.png new file mode 100644 index 0000000..656657d Binary files /dev/null and b/pictures/diagram_klaspng.png differ diff --git a/pictures/help_command.png b/pictures/help_command.png new file mode 100644 index 0000000..35fc840 Binary files /dev/null and b/pictures/help_command.png differ diff --git a/pictures/print_clients_command.png b/pictures/print_clients_command.png new file mode 100644 index 0000000..8983964 Binary files /dev/null and b/pictures/print_clients_command.png differ diff --git a/pictures/print_images_command.png b/pictures/print_images_command.png new file mode 100644 index 0000000..bc3ad90 Binary files /dev/null and b/pictures/print_images_command.png differ diff --git a/pictures/screenshot-client-app-running.png b/pictures/screenshot-client-app-running.png new file mode 100644 index 0000000..e3d4117 Binary files /dev/null and b/pictures/screenshot-client-app-running.png differ