mirror of
https://github.com/Lore09/Tesi-Magistrale.git
synced 2025-12-19 12:24:31 +00:00
137 lines
6.4 KiB
TeX
137 lines
6.4 KiB
TeX
In questo capitolo verrà mostrato il processo che porta alla compilazione del processo Go in un componente Wasm.\\
|
|
|
|
Se la fase di generazione è avvenuta con successo, all'interno del progetto dovrebbe essere presente una cartella chiamata \texttt{gen}, contenente diverse sotto-cartelle con il codice necessario per compilare i moduli Wasm.
|
|
|
|
\texttt{project/}
|
|
\dirtree{%
|
|
.1 workflow.yaml.
|
|
.1 tasks/.
|
|
.1 gen/.
|
|
.2 example\_component1.
|
|
.2 example\_component2.
|
|
}
|
|
|
|
\section{Wasm Builder}
|
|
|
|
A questo punto può essere invocato il componente \texttt{build}, che sostanzialmente esegue le seguenti operazioni:
|
|
\begin{enumerate}
|
|
\item Istanzia il client Docker utilizzando l'apposito SDK\footnote{\url{https://pypi.org/project/docker/}}.
|
|
\item Controlla se l'immagine \texttt{wash-build-image:latest} è presente. Se non lo è procede a buildarla utilizzando il dockerfile configurato.
|
|
\item Per ogni cartella presente dentro \texttt{gen} istanzia un container con \texttt{wash-build-image} come immagine e monta la cartella all'interno del container.
|
|
\item Attende la terminazione dei container.
|
|
\end{enumerate}
|
|
|
|
Si può notare come in questo caso le operazioni svolte dal framework siano limitate: la logica di build del componente e la pubblicazione dell'artifact OCI sono infatti delegate alle istanze in esecuzione su Docker.
|
|
|
|
\subsection{Wash build image}
|
|
|
|
Approfondiamo ora il meccanismo utilizzato per compilare i componenti Wasm, iniziando dal Dockerfile che descrive l'immagine di base utilizzata, mostrato nel Listing \ref{code:wash_buil_image_dockerfile}.
|
|
|
|
\begin{lstlisting}[language=Dockerfile, caption={wash-build-image Dockerfile}, captionpos=b, label={code:wash_buil_image_dockerfile}, basicstyle=\ttfamily\small]
|
|
FROM ubuntu:24.04 AS wash-build-image
|
|
|
|
# Install dependencies and tools
|
|
RUN apt-get update && apt-get install -y curl wget tar ...
|
|
|
|
# ----------------- Install WasmCloud -----------------
|
|
RUN curl -s "https://packagecloud.io/install/repositories/wasmcloud/core/script.deb.sh" | bash && \
|
|
apt-get install -y wash
|
|
|
|
# ----------------- Install Go 1.23 -----------------
|
|
RUN wget https://go.dev/dl/go1.23.4.linux-amd64.tar.gz && \
|
|
tar -C /usr/local -xzf go1.23.4.linux-amd64.tar.gz && \
|
|
rm go1.23.4.linux-amd64.tar.gz
|
|
|
|
# Set Go environment variables
|
|
ENV PATH="/usr/local/go/bin:${PATH}"
|
|
ENV GOPATH="/go"
|
|
ENV GOROOT="/usr/local/go"
|
|
|
|
# ----------------- Install TinyGo 0.34.0 -----------------
|
|
RUN wget https://github.com/tinygo-org/tinygo/releases/download/v0.34.0/tinygo_0.34.0_amd64.deb && \
|
|
dpkg -i tinygo_0.34.0_amd64.deb && \
|
|
rm tinygo_0.34.0_amd64.deb
|
|
|
|
# ----------------- Install Rust -----------------
|
|
# Install Rust
|
|
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y && \
|
|
. "$HOME/.cargo/env" && \
|
|
cargo install --locked wasm-tools
|
|
|
|
# Set Rust environment variables
|
|
ENV PATH="/root/.cargo/bin:${PATH}"
|
|
|
|
# Verify installations
|
|
RUN go version && tinygo version && cargo --version && wash --version && wasm-tools --version
|
|
|
|
# ----------------- Build the WasmCloud module -----------------
|
|
FROM wash-build-image
|
|
|
|
RUN mkdir /app
|
|
WORKDIR /app
|
|
|
|
# Install go dependencies, build the wasm module, push it to the registry
|
|
CMD ["sh", "-c", "go env -w GOFLAGS=-buildvcs=false && go mod download && go mod verify && wash build && wash push $REGISTRY build/*.wasm && chown -R ${HOST_UID}:${HOST_GID} ."]
|
|
\end{lstlisting}
|
|
|
|
Il Dockerfile è strutturato in due fasi:
|
|
\begin{enumerate}
|
|
\item \textbf{Fase 1}: vengono installate le dipendenze di Go, TinyGo, Rust e la shell di wasmCloud.
|
|
\item \textbf{Fase 2}: viene predisposta l'immagine per la compilazione dei moduli Wasm.
|
|
\end{enumerate}
|
|
|
|
La preparazione della compilazione avviene dentro l'istruzione CMD, che infatti contiene:
|
|
\begin{itemize}
|
|
\item Istruzioni per risolvere le dipendenze di go ed installarle nel progetto. In questo modo l'utente può aggiungere librerie supportate e il builder si occuperà di installarle nel progetto.
|
|
\item Comando \texttt{wash build} che esegue la compilazione del progetto e genera il componente Wasm all'interno della cartella \texttt{gen}.
|
|
\item Comando \texttt{wash push} che pubblica il componente Wasm come artifact OCI sul registry passato come configurazione.
|
|
\item Istruzione per impostare i permessi sui file generati, necessario per poter gestire correttamente i files tramite Python.
|
|
\end{itemize}
|
|
|
|
\subsection{Istanziamento container}
|
|
|
|
Questo approccio consente di utilizzare una sola immagine per tutte le operazioni di build: le configurazioni dinamiche avvengono tramite variabili d'ambiente e i file da buildare vengono montati come volume al posto della cartella \texttt{/app}, come possiamo notare dal Listing \ref{code:build} contenente un estratto di codice del componente \texttt{build}:
|
|
|
|
\begin{lstlisting}[language=python, caption={Build componente Wasm con Docker}, captionpos=b, label={code:build}]
|
|
def __build_wasm(task_dir, client, reg_user, reg_pass, detached, wait_list):
|
|
oci_url = wadm['spec']['components'][0]['properties']['image']
|
|
name = wadm['spec']['components'][0]['name'] + '-build'
|
|
...
|
|
# Build componente Wasm
|
|
print(f" - Building WASM module {oci_url}")
|
|
container = client.containers.run(
|
|
"wash-build-image:latest",
|
|
environment=[f'REGISTRY={oci_url}',
|
|
f'WASH_REG_USER={reg_user}',
|
|
f'WASH_REG_PASSWORD={reg_pass}',
|
|
f'HOST_UID={uid}',
|
|
f'HOST_GID={gid}'],
|
|
volumes={os.path.abspath(task_dir): {'bind': '/app', 'mode': 'rw'}},
|
|
remove = True,
|
|
detach = True,
|
|
name = name
|
|
)
|
|
|
|
# Build sequenziale o parallela
|
|
if detached == 'False':
|
|
container.wait()
|
|
else:
|
|
wait_list.append(name)
|
|
\end{lstlisting}
|
|
|
|
\subsection{Esecuzione parallelizzata}
|
|
|
|
Il processo di build può essere eseguito in modalità sequenziale o parallela, a seconda della configurazione delle variabili d'ambiente. Questo comportamento è gestito tramite la flag \texttt{detach}, che permette di avviare i container in modo asincrono. In questa modalità, viene utilizzata una waiting list per istanziare tutti i container in parallelo e attendere il completamento dell'operazione di build.\\
|
|
|
|
\section{Processo completo}
|
|
|
|
L'intero processo di build viene mostrato nella Figura [\ref{fig:impl_build}]:
|
|
|
|
\FloatBarrier
|
|
\begin{figure}[h]
|
|
\centering
|
|
\includegraphics[width=\textwidth]{img/schemi/schemi-implementazione-build.drawio.pdf}
|
|
\caption{Processo di Build componente Wasm}
|
|
\label{fig:impl_build}
|
|
\end{figure}
|
|
\FloatBarrier |