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 @@
+
+
+
+
\ 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