Use lstinline to display inline code instead of texttt

This commit is contained in:
Kristóf Tóth 2018-12-02 16:44:31 +01:00
parent fab9861d0d
commit ce8cad2ac4
6 changed files with 76 additions and 79 deletions

View File

@ -16,7 +16,7 @@ content using TFW.
The purpose of this chapter is to further detail the built-in components The purpose of this chapter is to further detail the built-in components
provided by the framework. provided by the framework.
As previously mentioned, these components are implemented as event handlers As previously mentioned, these components are implemented as event handlers
running in the \texttt{solvable} Docker container and frontend running in the \code{solvable} Docker container and frontend
components written in Angular. components written in Angular.
For instance the built-in code editor requires a frontend component and an event For instance the built-in code editor requires a frontend component and an event
handler to function properly, while the frontend component responsible for handler to function properly, while the frontend component responsible for
@ -36,14 +36,14 @@ For example, to inject a command into the terminal one would use a message like
} }
} }
\end{lstlisting} \end{lstlisting}
Notice the \texttt{\textbackslash{}n} at the end of the command. Notice the \code{\n} at the end of the command.
By including a newline character, we are also capable of executing commands in the By including a newline character, we are also capable of executing commands in the
user's terminal. user's terminal.
Were this newline omitted, the command would only be written to the terminal Were this newline omitted, the command would only be written to the terminal
(but not automatically executed) for users to inspect and potentially execute themselves. (but not automatically executed) for users to inspect and potentially execute themselves.
Some components emit or broadcast messages on specific events, for instance the Some components emit or broadcast messages on specific events, for instance the
\texttt{FSMManagingEventHandler} broadcasts the following message on state transitions: \code{FSMManagingEventHandler} broadcasts the following message on state transitions:
\begin{lstlisting}[captionpos=b,caption={An FSM Update message}] \begin{lstlisting}[captionpos=b,caption={An FSM Update message}]
{ {
"key": "fsm_update", "key": "fsm_update",
@ -97,7 +97,7 @@ The timing of pauses and messages is based on the \emph{WPM} --- or Words Per Mi
set by developers according to their specific use cases. set by developers according to their specific use cases.
This creates an experience similar to chatting with someone in real time, as the time This creates an experience similar to chatting with someone in real time, as the time
it takes for each message to be displayed is depending on the lenght of the previous message. it takes for each message to be displayed is depending on the lenght of the previous message.
This illusion is made possible through appropriate \texttt{setTimeout()} calls in This illusion is made possible through appropriate \code{setTimeout()} calls in
TypeScript and some elementary math to calculate the proper delays in milliseconds based on TypeScript and some elementary math to calculate the proper delays in milliseconds based on
message lengths: message lengths:
@ -110,7 +110,7 @@ message lengths:
This is the code editor integrated into the frontend of the framework. This is the code editor integrated into the frontend of the framework.
It allows users to select, display and edit files. It allows users to select, display and edit files.
Developers can configure which directory on the file system of the \texttt{solvable} Developers can configure which directory on the file system of the \code{solvable}
container should the editor list files from. container should the editor list files from.
The editor features the ``Deploy'' button referred to earlier in this paper, which is The editor features the ``Deploy'' button referred to earlier in this paper, which is
capable of restarting processes that might execute a file visible in the editor. capable of restarting processes that might execute a file visible in the editor.
@ -136,11 +136,11 @@ to display, that file is automatially displayed on a new tab in the IDE.
This allows for really interesting demo opportunities. This allows for really interesting demo opportunities.
Lets say I create a file using the terminal on the frontend by executing the Lets say I create a file using the terminal on the frontend by executing the
command \texttt{touch file.txt}. A new tab on the editor automatically command \code{touch file.txt}. A new tab on the editor automatically
appears. If I select it I can confirm that I have successfully created an appears. If I select it I can confirm that I have successfully created an
empty file. empty file.
After this let's run a \texttt{while} cycle in the command line which After this let's run a \code{while} cycle in the command line which
peroadically appends some text to \texttt{file.txt}: peroadically appends some text to \code{file.txt}:
\begin{lstlisting}[captionpos=b,caption={Bash While Cycle Writing to a File Periodically}, \begin{lstlisting}[captionpos=b,caption={Bash While Cycle Writing to a File Periodically},
language=bash] language=bash]
while true while true
@ -183,9 +183,9 @@ terminal emulator to do so.
This component has a tiny server process which is managed by a TFW event handler. This component has a tiny server process which is managed by a TFW event handler.
This small server is responsible for spawning bash sessions and This small server is responsible for spawning bash sessions and
unix pseudoterminals (or \texttt{pty}s) in the \texttt{solvable} Docker unix pseudoterminals (or \code{pty}s) in the \code{solvable} Docker
container. container.
It is also responsible for connecting the master end of the \texttt{pty} to the It is also responsible for connecting the master end of the \code{pty} to the
emulator running in your browser and the slave end to the bash session it has emulator running in your browser and the slave end to the bash session it has
spawned. spawned.
This way users are able to work in the shell displayed on the frontend just like This way users are able to work in the shell displayed on the frontend just like
@ -212,21 +212,21 @@ monitoring solution such as Sysdig%
\footnote{\href{https://sysdig.comq}{https://sysdig.com}}. \footnote{\href{https://sysdig.comq}{https://sysdig.com}}.
I deemed most simiar systems a huge overkill to implement this functionality, and their I deemed most simiar systems a huge overkill to implement this functionality, and their
memory footprints are not something we could afford here. memory footprints are not something we could afford here.
Another way would be to use \texttt{pam\_tty\_audit.so} in the PAM% Another way would be to use \code{pam_tty_audit.so} in the PAM%
\footnote{Linux Pluggable Authentication Modules: \footnote{Linux Pluggable Authentication Modules:
\href{http://man7.org/linux/man-pages/man3/pam.3.html} \href{http://man7.org/linux/man-pages/man3/pam.3.html}
{http://man7.org/linux/man-pages/man3/pam.3.html}} {http://man7.org/linux/man-pages/man3/pam.3.html}}
configurations responsible for logins, as this allows for various TTY auditing functions, configurations responsible for logins, as this allows for various TTY auditing functions,
but I have found an ever simpler approach to the problem in the end. but I have found an ever simpler approach to the problem in the end.
By using the inotify system built into TFW, I can set up the user's environment in By using the inotify system built into TFW, I can set up the user's environment in
such a way, that I can enforce and determine the location of the bash \texttt{HISTFILE}% such a way, that I can enforce and determine the location of the bash \code{HISTFILE}%
\footnote{This environment variable contains the path to the file bash writes command \footnote{This environment variable contains the path to the file bash writes command
history to} history to}
of the user. of the user.
This way I can monitor changes made to this file and read the commands executed This way I can monitor changes made to this file and read the commands executed
by the user from it. by the user from it.
It is important to keep in mind that the user is able to ``sabotage'' this method% It is important to keep in mind that the user is able to ``sabotage'' this method%
\footnote{By unsetting the \texttt{HISTFILE} envvar for example}, \footnote{By unsetting the \code{HISTFILE} envvar for example},
but that should not be an issue as this is not a feature that is intended to be but that should not be an issue as this is not a feature that is intended to be
used in competitive environments (and if the users of a tutorial intentionally used in competitive environments (and if the users of a tutorial intentionally
break the system under themselves, well, good for them). break the system under themselves, well, good for them).
@ -248,7 +248,7 @@ experience similar to working in an IDE on your laptop.
\section{Process Management}\label{processmanagement} \section{Process Management}\label{processmanagement}
The framework includes an event handler capable of managing processes running inside The framework includes an event handler capable of managing processes running inside
the \texttt{solvable} Docker container. the \code{solvable} Docker container.
It's capabilities include starting, stopping and restarting processes. It's capabilities include starting, stopping and restarting processes.
It is also capable of emitting the standard out or standard error logs of processes It is also capable of emitting the standard out or standard error logs of processes
(by broadcasting TFW messages). (by broadcasting TFW messages).
@ -273,17 +273,17 @@ a complex system could come with.
I'll briefly explain such a bug, which I've found to be immersely exciting. I'll briefly explain such a bug, which I've found to be immersely exciting.
During the initial development of this feature all processes inside the During the initial development of this feature all processes inside the
\texttt{solvable} Docker container were writing their logs to files \code{solvable} Docker container were writing their logs to files
in the FHS% in the FHS%
\footnote{The File Hierarchy Standard is a standard maintained by the Linux foundation, \footnote{The File Hierarchy Standard is a standard maintained by the Linux foundation,
defining a common directory structure for compliant systems. See defining a common directory structure for compliant systems. See
\href{https://wiki.linuxfoundation.org/lsb/fhs}{https://wiki.linuxfoundation.org/lsb/fhs}} \href{https://wiki.linuxfoundation.org/lsb/fhs}{https://wiki.linuxfoundation.org/lsb/fhs}}
location \texttt{/tmp/}. location \code{/tmp/}.
All logs coming from the container itself were also logged to this location. All logs coming from the container itself were also logged to this location.
This had caused an infinite recursion: when a process would write to \texttt{/tmp/} This had caused an infinite recursion: when a process would write to \code{/tmp/}
inotify would invoke a process that would also log to that location causing the kernel to inotify would invoke a process that would also log to that location causing the kernel to
emit more inotify events, which in turn would cause more and more new proesses to spawn emit more inotify events, which in turn would cause more and more new proesses to spawn
and write to \texttt{/tmp/}, causing the whole procedure to repeat again and again. and write to \code{/tmp/}, causing the whole procedure to repeat again and again.
This continued until my machine would start to run out of memory and stat swapping This continued until my machine would start to run out of memory and stat swapping
pages to disk% pages to disk%
\footnote{When a modern operating system runs out of physical RAM, it is going to swap \footnote{When a modern operating system runs out of physical RAM, it is going to swap
@ -296,7 +296,7 @@ fascinating phenomenon, but those were \emph{very} fun hours.
\section{FSM Management} \section{FSM Management}
I have already mentioned the event handler called \texttt{FSMManagingEventHandler}, I have already mentioned the event handler called \code{FSMManagingEventHandler},
which is responsible for managing the framework FSM. which is responsible for managing the framework FSM.
For completeness I chose to include it on this chapter as well. For completeness I chose to include it on this chapter as well.
The API it exposes through TFW messages allows client code to attempt stepping the The API it exposes through TFW messages allows client code to attempt stepping the

View File

@ -4,14 +4,14 @@
It is important to understand that the Tutorial Framework is currently implemented as It is important to understand that the Tutorial Framework is currently implemented as
two Docker images: two Docker images:
\begin{itemize} \begin{itemize}
\item the \texttt{solvable} image is responsible for running the framework and the client \item the \code{solvable} image is responsible for running the framework and the client
code depending on it code depending on it
\item the \texttt{controller} image is responsible for solution checking (to figure out \item the \code{controller} image is responsible for solution checking (to figure out
whether the user completed the tutorial or not) whether the user completed the tutorial or not)
\end{itemize} \end{itemize}
During most of this capter I am going to be discussing the \texttt{solvable} Docker image, During most of this capter I am going to be discussing the \code{solvable} Docker image,
with the exception of section~\ref{solutioncheck}, where I will dive into how the with the exception of Section~\ref{solutioncheck}, where I will dive into how the
\texttt{controller} image is implemented. \code{controller} image is implemented.
The most important feature of the framework is it's messaging system. The most important feature of the framework is it's messaging system.
Basically what we need is a system where processes running inside a Docker container Basically what we need is a system where processes running inside a Docker container
@ -51,7 +51,7 @@ of your website (and as such requiring to go over the whole TCP handshake and th
HTTP request-response on each update). HTTP request-response on each update).
This has been superseded by WebSockets around 2011, which provide a full-duplex This has been superseded by WebSockets around 2011, which provide a full-duplex
communication channel over TCP between your browser and the server. communication channel over TCP between your browser and the server.
This is done by initiation a protocol handshake using the \texttt{Connection: Upgrade} This is done by initiation a protocol handshake using the \code{Connection: Upgrade}
HTTP header, which establishes a premanent socket connection between the browser HTTP header, which establishes a premanent socket connection between the browser
and the server. and the server.
This allows for communication with lower overhead and latency facilitating efficient This allows for communication with lower overhead and latency facilitating efficient
@ -85,7 +85,7 @@ A few examples of top contenders and reasons for not using them in the end:
\item The handling of raw TCP sockets would involve lot's of boilerplate logic that \item The handling of raw TCP sockets would involve lot's of boilerplate logic that
already have quality implementations in messaging libraries: i.e.\ making sure that already have quality implementations in messaging libraries: i.e.\ making sure that
all bytes are sent or received both require checking the return values of the all bytes are sent or received both require checking the return values of the
libc \texttt{send()} and \texttt{recv()} system calls, while ZMQ takes care of this libc \code{send()} and \code{recv()} system calls, while ZMQ takes care of this
extra logic involved and even provides higher level messaging patterns such as extra logic involved and even provides higher level messaging patterns such as
subscribe-publish, which would need to be implemented on top of raw sockets again. subscribe-publish, which would need to be implemented on top of raw sockets again.
\item Using something like gRPC\footnote{\href{https://grpc.io}{https://grpc.io}} \item Using something like gRPC\footnote{\href{https://grpc.io}{https://grpc.io}}
@ -113,10 +113,10 @@ Architecturally TFW consists of four main components:
\item \textbf{TFW (proxy) server}: responsible for message routing/proxying \item \textbf{TFW (proxy) server}: responsible for message routing/proxying
between the frontend and event handlers between the frontend and event handlers
\item \textbf{TFW FSM}: a finite state machine responsible for tracking user progress, \item \textbf{TFW FSM}: a finite state machine responsible for tracking user progress,
that is implemented as an event handler called \texttt{FSMManagingEventHandler} that is implemented as an event handler called \code{FSMManagingEventHandler}
\end{itemize} \end{itemize}
Note that it is important to keep in mind that as I've mentioned previously, Note that it is important to keep in mind that as I've mentioned previously,
the TFW Server and event handlers reside in the \texttt{solvable} Docker container. the TFW Server and event handlers reside in the \code{solvable} Docker container.
They all run in separate processes and only communicate using ZeroMQ sockets. They all run in separate processes and only communicate using ZeroMQ sockets.
In the following sections I am going to explain each of the main components in In the following sections I am going to explain each of the main components in
@ -147,17 +147,17 @@ Let's inspect further what a valid TFW message might look like:
} }
\end{lstlisting} \end{lstlisting}
All valid messages \emph{must} include a \texttt{key} field as this is used by the All valid messages \emph{must} include a \code{key} field as this is used by the
framework for addressing: event handlers and frontend components subscribe to one framework for addressing: event handlers and frontend components subscribe to one
or more \texttt{key}s and only receive messages with \texttt{key}s they have or more \code{key}s and only receive messages with \code{key}s they have
subscribed to. subscribed to.
It is possible to send a message with an empty key, however these messages will not It is possible to send a message with an empty key, however these messages will not
be forwarded by the TFW server (but will reach it, so in case the target of a message be forwarded by the TFW server (but will reach it, so in case the target of a message
is the TFW server exclusively, an empty \texttt{key} can may used). is the TFW server exclusively, an empty \code{key} can may used).
The rest of the fields are optional, but most messages will carry something The rest of the fields are optional, but most messages will carry something
in their \texttt{data} field. in their \code{data} field.
The purpose \texttt{trigger} and \texttt{signature} fields will be detailed The purpose \code{trigger} and \code{signature} fields will be detailed
at a later point in this paper. at a later point in this paper.
\subsection{Networking Details} \subsection{Networking Details}
@ -171,8 +171,8 @@ the frontend via WebSockets.
The TFW server is also capable of ``reflecting'' messages back to the side they were The TFW server is also capable of ``reflecting'' messages back to the side they were
received on (to faciliate event handler to event handler for instance), or broadcast received on (to faciliate event handler to event handler for instance), or broadcast
messages to all components. messages to all components.
This is possible by embedding a whole TFW message in the \texttt{data} field of This is possible by embedding a whole TFW message in the \code{data} field of
an outer wrapper message with a special \texttt{key} that signals to the TFW server that an outer wrapper message with a special \code{key} that signals to the TFW server that
this message requires special attention. this message requires special attention.
An example of this would be: An example of this would be:
\begin{lstlisting}[captionpos=b,caption={Broadcasting and mirroring TFW messages}] \begin{lstlisting}[captionpos=b,caption={Broadcasting and mirroring TFW messages}]
@ -187,12 +187,12 @@ An example of this would be:
} }
} }
\end{lstlisting} \end{lstlisting}
Any invalid messages (not valid JSON or no \texttt{key} field present) are ignored Any invalid messages (not valid JSON or no \code{key} field present) are ignored
by the TFW server. by the TFW server.
\subsection{Event Handlers} \subsection{Event Handlers}
Event handlers are processes running in the \texttt{solvable} Docker container Event handlers are processes running in the \code{solvable} Docker container
that subscribe to specific message types using ZeroMQ sockets. that subscribe to specific message types using ZeroMQ sockets.
As discussed earlier, using ZeroMQ allows developers to implement event handlers As discussed earlier, using ZeroMQ allows developers to implement event handlers
in a wide variety of programming languages. in a wide variety of programming languages.
@ -253,7 +253,7 @@ This code editor is essentially a Monaco editor%
{https://microsoft.github.io/monaco-editor/}} {https://microsoft.github.io/monaco-editor/}}
instance integrated into Angular and upgraded with the capability to instance integrated into Angular and upgraded with the capability to
exchanges messages with an event handler to save, read and edit files exchanges messages with an event handler to save, read and edit files
that reside in the writeable file system of the \texttt{solvable} that reside in the writeable file system of the \code{solvable}
Docker container. Docker container.
All of the built-ins come with full API documentation explaining what they do All of the built-ins come with full API documentation explaining what they do
@ -337,7 +337,7 @@ state transitions, or onentering and exiting a state.
It is \emph{very} important to be aware of these callbacks, as much of the It is \emph{very} important to be aware of these callbacks, as much of the
actual tutorial logic is often going to be implemented in these. actual tutorial logic is often going to be implemented in these.
Architecturally a built-in event handler called \texttt{FSMManagingEventHandler} Architecturally a built-in event handler called \code{FSMManagingEventHandler}
is capable of managing the FSM defined by clients. is capable of managing the FSM defined by clients.
The responsibilities of said event handler include: The responsibilities of said event handler include:
\begin{itemize} \begin{itemize}
@ -347,16 +347,16 @@ The responsibilities of said event handler include:
such as successful transitions such as successful transitions
\end{itemize} \end{itemize}
The \texttt{trigger} field of a message can be used to step the framework FSM The \code{trigger} field of a message can be used to step the framework FSM
if all preconditions are met. if all preconditions are met.
The way this works is if the TFW server encounters a message with a The way this works is if the TFW server encounters a message with a
\texttt{trigger} defined, it notifies the event handler managing \code{trigger} defined, it notifies the event handler managing
the state machine. the state machine.
Since messages can come from unauthenticated sources, it is possible to Since messages can come from unauthenticated sources, it is possible to
enforce the authentication of privileged messages, such as messages containing a \texttt{trigger}. enforce the authentication of privileged messages, such as messages containing a \code{trigger}.
The framework allows trusted code to access a cryptographic key on the file system, which The framework allows trusted code to access a cryptographic key on the file system, which
can be used to digitally sign messages (this is what the \texttt{signature} message can be used to digitally sign messages (this is what the \code{signature} message
field is designed for). field is designed for).
In this case the TFW server will only forward privileged messages that In this case the TFW server will only forward privileged messages that
have a valid signature. have a valid signature.
@ -364,9 +364,9 @@ have a valid signature.
\subsection{Solution checking}\label{solutioncheck} \subsection{Solution checking}\label{solutioncheck}
Traditionally most challenges on the Avatao platform implement a Docker image called Traditionally most challenges on the Avatao platform implement a Docker image called
\texttt{controller}, which is responsible for detecting the successful \code{controller}, which is responsible for detecting the successful
solution of a challenge. solution of a challenge.
When using the Tutorial Framework a pre-implemented \texttt{controller} When using the Tutorial Framework a pre-implemented \code{controller}
image is available, which listens to messages emitted by the image is available, which listens to messages emitted by the
framework FSM, and detects if the final state defined by developers is reached. framework FSM, and detects if the final state defined by developers is reached.
This means that if content creators implement a proper FSM, the solution checking This means that if content creators implement a proper FSM, the solution checking

View File

@ -105,7 +105,7 @@ After I got this working I was looking into writing hacky bash scripts to automa
required to complete the challenge in order to make it easier for me to record the solution, required to complete the challenge in order to make it easier for me to record the solution,
as I have often found myself recording over and over again for a demo without any mistakes. as I have often found myself recording over and over again for a demo without any mistakes.
During the time I was playing around with this idea, researching possible solutions have led me During the time I was playing around with this idea, researching possible solutions have led me
to a hidden gem of a project on GitHub called \texttt{demo-magic}% to a hidden gem of a project on GitHub called \code{demo-magic}%
\footnote{\href{https://github.com/paxtonhare/demo-magic}{https://github.com/paxtonhare/demo-magic}}, \footnote{\href{https://github.com/paxtonhare/demo-magic}{https://github.com/paxtonhare/demo-magic}},
which is esentially a bash script that simulates someone typing into a terminal and executing which is esentially a bash script that simulates someone typing into a terminal and executing
commands. commands.
@ -118,7 +118,7 @@ Soon after recording demo videos was not even necessary anymore, as I have start
the solution script with the challenge code itself, making it toggleable using build-time the solution script with the challenge code itself, making it toggleable using build-time
variables. variables.
Should the solution script be enabled, the challenge would automatically start% Should the solution script be enabled, the challenge would automatically start%
\footnote{I did this by injecting the solution script into the user's \texttt{.bashrc} file} \footnote{I did this by injecting the solution script into the user's \code{.bashrc} file}
completing itself in the terminal integrated into it's frontend, often even explaining the completing itself in the terminal integrated into it's frontend, often even explaining the
commands executed during the solution process. commands executed during the solution process.

View File

@ -2,7 +2,7 @@
In this section I am going to dive into further detail on how client code is supposed In this section I am going to dive into further detail on how client code is supposed
to use the framework, some of the design decisions behind this and how everything is to use the framework, some of the design decisions behind this and how everything is
is integrated into the \texttt{solvable} Docker image. is integrated into the \code{solvable} Docker image.
To use the framework one has to do several things to get started. To use the framework one has to do several things to get started.
The main points include: The main points include:
@ -25,7 +25,7 @@ framework.
This repository is a really simple client codebase that is suitable for This repository is a really simple client codebase that is suitable for
developing TFW itself as well (a good place to host tests for the framework). developing TFW itself as well (a good place to host tests for the framework).
It also provides an ``industry standard'' \texttt{hack} directory It also provides an ``industry standard'' \code{hack} directory
containing bash scripts that make the development of tutorials and TFW itself very convenient. containing bash scripts that make the development of tutorials and TFW itself very convenient.
These scripts span from bootstrapping a complete development environment in one command, These scripts span from bootstrapping a complete development environment in one command,
to building and running challenges based on the framework. to building and running challenges based on the framework.
@ -54,7 +54,7 @@ understanding of how the framework interacts with client code.
\end{lstlisting} \end{lstlisting}
\subsection{Avatao Configuration File} \subsection{Avatao Configuration File}
The \texttt{config.yml} file is an Avatao challenge configuration file, The \code{config.yml} file is an Avatao challenge configuration file,
which is used describe what kind of Docker containers implement a challenge, which is used describe what kind of Docker containers implement a challenge,
what ports do they expose talking what protocols, define the name of the what ports do they expose talking what protocols, define the name of the
excercise, it's difficulity, and so on. excercise, it's difficulity, and so on.
@ -63,12 +63,12 @@ The Tutorial Framework does not use this file, this is only required to run
the exercise in production, so it is mostly out of scope for this thesis. the exercise in production, so it is mostly out of scope for this thesis.
\subsection{Controller Image} \subsection{Controller Image}
It was previously mentioned that the \texttt{controller} Docker image is responsible It was previously mentioned that the \code{controller} Docker image is responsible
for the solution checking of challenges (whether the user has completed the exercise or not). for the solution checking of challenges (whether the user has completed the exercise or not).
Currently this image is maintained in the test-tutorial-framework repository. Currently this image is maintained in the test-tutorial-framework repository.
It is a really simple Python server which functions as a TFW event handler as well. It is a really simple Python server which functions as a TFW event handler as well.
It subscribes to the FSM update messages It subscribes to the FSM update messages
broadcasted by the \texttt{FSMManagingEventHandler}, we've previously discussed, broadcasted by the \code{FSMManagingEventHandler}, we've previously discussed,
this way it is capable of keeping track of the state of the tutorial, this way it is capable of keeping track of the state of the tutorial,
which allows it to detect if the final state of the FSM is reached. which allows it to detect if the final state of the FSM is reached.
@ -80,7 +80,7 @@ Currently the Tutorial Framework is maintained in three git repositories:
\item[test-tutorial-framework] An example tutorial built using baseimage and frontend \item[test-tutorial-framework] An example tutorial built using baseimage and frontend
\end{description} \end{description}
Every tutorial based on the framework must use the TFW baseimage as the parent of Every tutorial based on the framework must use the TFW baseimage as the parent of
it's own \texttt{solvable} image, using the \texttt{FROM}% it's own \code{solvable} image, using the \code{FROM}%
\footnote{\href{https://docs.docker.com/engine/reference/builder/\#from} \footnote{\href{https://docs.docker.com/engine/reference/builder/\#from}
{https://docs.docker.com/engine/reference/builder/\#from}} {https://docs.docker.com/engine/reference/builder/\#from}}
Dockerfile command. Dockerfile command.
@ -88,7 +88,7 @@ Being an example project of the framework this is the case with
test-tutorial-framework as well. test-tutorial-framework as well.
\section{Details of the Solvable Image} \section{Details of the Solvable Image}
Let us dive into greater detail on how the \texttt{solvable} Docker image of the Let us dive into greater detail on how the \code{solvable} Docker image of the
test-tutorial-framework operates. test-tutorial-framework operates.
The directory structure is as follows: The directory structure is as follows:
\begin{lstlisting} \begin{lstlisting}
@ -102,9 +102,9 @@ solvable/
I am going to discuss these one by one. I am going to discuss these one by one.
\subsection{Dockerfile} \subsection{Dockerfile}
Since this is a Docker image it must define a \texttt{Dockerfile}. Since this is a Docker image it must define a \code{Dockerfile}.
This image always uses the baseimage of the framework as a parent image. This image always uses the baseimage of the framework as a parent image.
Besides this developers can use this as a regular \texttt{Dockerfile} to work with as Besides this developers can use this as a regular \code{Dockerfile} to work with as
they see fit to implement their tutorial. they see fit to implement their tutorial.
\subsection{Frontend} \subsection{Frontend}
@ -124,7 +124,7 @@ very hard and impractial to do in practice.
Supervisor is a process control system designed to be able to work with Supervisor is a process control system designed to be able to work with
processes on UNIX-like operating systems. processes on UNIX-like operating systems.
When a tutorial built on TFW is started, the framework starts supervisor with When a tutorial built on TFW is started, the framework starts supervisor with
PID\footnote{Process ID, on UNIX-like systems the \texttt{init} program is the first PID\footnote{Process ID, on UNIX-like systems the \code{init} program is the first
process started} 1, which in turn starts all the programs defined process started} 1, which in turn starts all the programs defined
in this directory using supervisor configuration files. in this directory using supervisor configuration files.
For example, a developer would use a file similar to this to run a webserver For example, a developer would use a file similar to this to run a webserver
@ -141,7 +141,7 @@ can be managed by the framewok using API messages.
\subsection{Nginx} \subsection{Nginx}
For simplicity, exercises based on the framework only expose a single port from the For simplicity, exercises based on the framework only expose a single port from the
\texttt{solvable} container. \code{solvable} container.
This port is required to serve the frontend of the framework. This port is required to serve the frontend of the framework.
If this is the case, how do we run additional web applications to showcase vulnerabilies If this is the case, how do we run additional web applications to showcase vulnerabilies
on during the tutorial? on during the tutorial?
@ -167,7 +167,7 @@ What this means is that they are going to be serverd from a ``subdirectory'' of
for example ``/register'' will be served under ``/yoururl/register''. for example ``/register'' will be served under ``/yoururl/register''.
This means that all links in the final HTML must refer to the proxied urls, e.g.\ This means that all links in the final HTML must refer to the proxied urls, e.g.\
``/yoururl/register'' and server side redirects must point to the correct hrefs as well. ``/yoururl/register'' and server side redirects must point to the correct hrefs as well.
Idiomatically this is usually implemented by supplying a \texttt{BASEURL} Idiomatically this is usually implemented by supplying a \code{BASEURL}
to the application through an environment variable, so that it is able to set to the application through an environment variable, so that it is able to set
itself up correctly. itself up correctly.
@ -175,7 +175,7 @@ itself up correctly.
Behind the curtains, the Tutorial Framework uses some Dockerfile trickery to Behind the curtains, the Tutorial Framework uses some Dockerfile trickery to
faciliate the copying of supervisor and nginx configuration files to their correct faciliate the copying of supervisor and nginx configuration files to their correct
locations. locations.
Normally when one uses the \texttt{COPY}% Normally when one uses the \code{COPY}%
\footnote{\href{https://docs.docker.com/engine/reference/builder/\#copy} \footnote{\href{https://docs.docker.com/engine/reference/builder/\#copy}
{https://docs.docker.com/engine/reference/builder/\#copy}} {https://docs.docker.com/engine/reference/builder/\#copy}}
command to create a layer% command to create a layer%
@ -188,23 +188,23 @@ these configuration files that will be written by content developers do not even
exist. exist.
How could we copy files into an image layer that will be created in the future? How could we copy files into an image layer that will be created in the future?
It is possible to use a command called \texttt{ONBUILD}% It is possible to use a command called \code{ONBUILD}%
\footnote{\href{https://docs.docker.com/engine/reference/builder/\#onbuild} \footnote{\href{https://docs.docker.com/engine/reference/builder/\#onbuild}
{https://docs.docker.com/engine/reference/builder/\#onbuild}} {https://docs.docker.com/engine/reference/builder/\#onbuild}}
in the Dockerfile of a baseimage to delay another command in the Dockerfile of a baseimage to delay another command
to the point in time when other images will use the baseimage to the point in time when other images will use the baseimage
as a parent with the \texttt{FROM} command. This makes it possible to execute as a parent with the \code{FROM} command. This makes it possible to execute
commands in the build context of the descendant image. commands in the build context of the descendant image.
This is great, because the config files we need \emph{will} exist in the build This is great, because the config files we need \emph{will} exist in the build
context of the \texttt{solvable} image of test-tutorial-framework. context of the \code{solvable} image of test-tutorial-framework.
In practice this looks something like this in the baseimage \texttt{Dockerfile}: In practice this looks something like this in the baseimage \code{Dockerfile}:
\begin{lstlisting} \begin{lstlisting}
ONBUILD COPY ${BUILD_CONTEXT}/nginx/ ${TFW_NGINX_COMPONENTS} ONBUILD COPY ${BUILD_CONTEXT}/nginx/ ${TFW_NGINX_COMPONENTS}
ONBUILD COPY ${BUILD_CONTEXT}/supervisor/ ${TFW_SUPERVISORD_COMPONENTS} ONBUILD COPY ${BUILD_CONTEXT}/supervisor/ ${TFW_SUPERVISORD_COMPONENTS}
\end{lstlisting} \end{lstlisting}
\subsection{Source Directory} \subsection{Source Directory}
The \texttt{src} directory usually holds tutorial-specific code, such as The \code{src} directory usually holds tutorial-specific code, such as
the implementations of event handlers, the framework FSM, additional web applications the implementations of event handlers, the framework FSM, additional web applications
served by the exercise and generally anything that won't fit in the other, served by the exercise and generally anything that won't fit in the other,
framework-specific directories. framework-specific directories.
@ -227,11 +227,11 @@ It is possible to use this format to define a state machine like so:
caption={A Finite State Machine implemented in YAML}, caption={A Finite State Machine implemented in YAML},
captionpos=b captionpos=b
]{listings/test_fsm.yml} ]{listings/test_fsm.yml}
This state machine has 2 states, state 0 and 1. This state machine has two states, state \code{0} and \code{1}.
It defines a single transition between them. It defines a single transition between them, \code{step_1}.
On entering state 1 the FSM will write a message to the frontend messaging component On entering state \code{1} the FSM will write a message to the frontend messaging component
by invoking TFW library code in Python. by invoking TFW library code using Python.
The transition can only occour if the file \texttt{allow\_step\_1} exists. The transition can only occour if the file \code{allow_step_1} exists.
YAML based state machine implementations also allow the usage of the Jinja2% YAML based state machine implementations also allow the usage of the Jinja2%
\footnote{\href{http://jinja.pocoo.org/docs/2.10/}{http://jinja.pocoo.org/docs/2.10/}} \footnote{\href{http://jinja.pocoo.org/docs/2.10/}{http://jinja.pocoo.org/docs/2.10/}}
@ -258,11 +258,11 @@ Python as well, it is going to be easier to interface with library code.
\section{Configuring Components} \section{Configuring Components}
The configuration of built-ins is generally done in two different ways. The configuration of built-ins is generally done in two different ways.
For the frontend (Angular) side, developers can edit a \texttt{config.ts} file, For the frontend (Angular) side, developers can edit a \code{config.ts} file,
which is full of key-value pairs of configurable frontend functionality. which is full of key-value pairs of configurable frontend functionality.
These pairs are generally pretty self-documenting: These pairs are generally pretty self-documenting:
\lstinputlisting[ \lstinputlisting[
caption={Example of the frontend \texttt{config.ts} file (stripped down to save space)}, caption={Example of the frontend \code{config.ts} file (stripped down to save space)},
captionpos=b captionpos=b
]{listings/config.ts} ]{listings/config.ts}
Configuring built-in event handlers is possible by editing the Python file they are Configuring built-in event handlers is possible by editing the Python file they are
@ -283,7 +283,7 @@ This script is distributed as a bash one-liner command, like so:
\begin{lstlisting}[language=bash] \begin{lstlisting}[language=bash]
bash -c "$(curl -fsSL https://git.io/vxBfj)" bash -c "$(curl -fsSL https://git.io/vxBfj)"
\end{lstlisting} \end{lstlisting}
This command downloads a script using \texttt{curl}, then executes the downloaded This command downloads a script using \code{curl}, then executes the downloaded
script in bash. script in bash.
In the open source community it is quite common to distribute installers this way% In the open source community it is quite common to distribute installers this way%
\footnote{A good example of this is oh-my-zsh \footnote{A good example of this is oh-my-zsh
@ -318,9 +318,9 @@ The bootstrap script clones the three TFW repositories and does several steps
to create a working environment: to create a working environment:
\begin{itemize} \begin{itemize}
\item It builds the newest version of the TFW baseimage locally \item It builds the newest version of the TFW baseimage locally
\item It pins the version tag in \texttt{solvable/Dockerfile}, \item It pins the version tag in \code{solvable/Dockerfile},
so that this newly-built version will be used by the tutorial so that this newly-built version will be used by the tutorial
\item It places the latest frontend in \texttt{solvable/frontend} with \item It places the latest frontend in \code{solvable/frontend} with
depencendies installed depencendies installed
\end{itemize} \end{itemize}
It is important to note that this script \emph{does not} install anything system-wide, It is important to note that this script \emph{does not} install anything system-wide,

View File

@ -15,10 +15,6 @@
} }
\RequirePackage[bottom,hang,flushmargin]{footmisc} \RequirePackage[bottom,hang,flushmargin]{footmisc}
\definecolor{andigray}{RGB}{237,237,237}
\sethlcolor{andigray}
\newcommand{\code}[1]{\hl{\mbox{#1}}}
\newtheorem*{note}{Note} \newtheorem*{note}{Note}
\newcommand{\pic}[3][width=\textwidth] \newcommand{\pic}[3][width=\textwidth]

View File

@ -20,6 +20,7 @@
aboveskip=15pt, aboveskip=15pt,
belowskip=15pt, belowskip=15pt,
} }
\newcommand{\code}{\lstinline}
\setmainfont{Constantia} \setmainfont{Constantia}
\setmonofont{DejaVu Sans Mono} \setmonofont{DejaVu Sans Mono}