1
0
mirror of https://github.com/avatao-content/test-tutorial-framework synced 2024-11-14 21:37:17 +00:00
test-tutorial-framework/README.md

188 lines
8.5 KiB
Markdown
Raw Normal View History

2018-03-30 20:14:11 +00:00
# tutorial-framework test
This is an example playground project built via TFW.
It is a good starting point to build your own challenges from and will host automated tests in the future.
It also gives home to several useful scripts in the `hack` folder to speed up development.
## Getting started
TFW consists of 3 repositories:
- `baseimage-tutorial-framework` Docker baseimage
- `frontend-tutorial-framework` Angular frontend
- `test-tutorial-framework` (this repo)
See the documentation of each in their `README.md` files.
To learn the stuff you need to know about TFW in order to get started you should consult the `baseimage-tutorial-framework` repo first.
2018-03-30 20:14:11 +00:00
Getting started with creating challenges using the framework *setting up a development environment, building, running and such* is documented here.
2018-03-30 20:14:11 +00:00
## Setting up a development environment
2018-03-31 16:23:11 +00:00
Just copy and paste the following command in a terminal:
`bash -c "$(curl -fsSL https://git.io/vxBfj)"`
2018-03-31 16:23:11 +00:00
> You have trust issues regarding the public key infrastructure? You can request a checksum authenticated version of the installer command from our team!
This will set up a dev environment based on `test-tutorial-framework` just for you:
- it builds the latest release of the framework Docker baseimage locally
- it pins `solvable/Dockerfile` to use the this image
- it includes the latest frontend in `solvable/frontend` with dependencies installed
2018-03-31 16:23:11 +00:00
## Building & running
### Automated
Our magical bash script `hack/tfw.sh` can handle everything for you. Just run it without any arguments to see usage information.
It is advisable to run the frontend locally while developing to avoid really looooong build times. The `hack/tfw.sh` script handles this for you automagically.
### Doing it manually
In case you **must** do it for some reason you can build & run manually.
Note that this is relatively painful and you should use the `hack/tfw.sh` script when possible.
Building without frontend execute from project root:
`docker build -t test-tutorial-framework -f solvable/Dockerfile --build-arg BUILD_CONTEXT=solvable --build-arg NOFRONTEND=1 .`
This will create a Docker image without the frontend, which you can run locally. For procudtion builds exclude the argument `--build-arg NOFRONTEND=1` to include a frontend instance.
Running execute:
`docker run --rm -p 8888:8888 -e AVATAO_SECRET=secret test-tutorial-framework`
In case of a frontendless build (with `--build-arg NOFRONTEND=1`) you will need to run `yarn start` from the `solvable/frontend` directory as well. This will serve the frontend on `http://localhost:4200`.
If you've created a production build (without `--build-arg NOFRONTEND=1`) you don't have to run the frontend locally and you can access the challenge on `http://localhost:8888`.
## Getting our hands dirty
The repository of a tutorial-framework based challenge is quite similar to a regular challenge.
The project root should look something like this:
2018-04-18 08:49:10 +00:00
```text
your_repo
├── solvable
│ └── [TFW based Docker image]
├── controller
│ └── [solution checking]
├── metadata
│ └── [challenge descriptions, writeups, etc.]
└── config.yml
```
2018-04-17 16:04:59 +00:00
The only notable difference is that the `solvable` Docker image is a child of our baseimage: `solvable/Dockerfile` begins with `FROM eu.gcr.io/avatao-challengestore/tutorial-framework`.
From now on we are going to focus on the `solvable` image.
### Basics of a TFW based challenge
Let us take a closer look on `solvable`:
2018-04-18 08:49:10 +00:00
```text
solvable
├── Dockerfile
├── nginx webserver configurations
├── supervisor process manager (init replacement)
├── frontend clone of the frontend-tutorial-framework repo with dependencies installed
2018-04-17 16:04:59 +00:00
└── src example source code
```
2018-04-17 15:39:57 +00:00
Note that our baseimage *requires* the `nginx`, `supervisor` and `frontend` folders to be in these **exact** locations, used as described below. This is a contract your image **must** comply.
2018-04-17 16:04:59 +00:00
The `src` directory is not a concept of TFW and you can call it however you like and put your version anywhere, just be sure to adjust your `Dockerfile` accordingly.
It contains a simple example of using TFW.
2018-04-17 15:39:57 +00:00
### nginx
All TFW based challenges expose a single port defined in the `TFW_PUBLIC_PORT` envvar which is set to `8888` by default.
This means that in order to listen on more than a single port we must use a reverse proxy.
2018-04-17 15:39:57 +00:00
Any `.conf` files in `solvable/nginx/` will be automatically included in the nginx configuration.
In case you want serve a website or service you must proxy it through `TFW_PUBLIC_PORT`.
2018-04-17 15:39:57 +00:00
This is really easy: just create a config file in `solvable/nginx/` similar to this one:
2018-04-18 08:49:10 +00:00
```text
location /yoururl {
proxy_pass http://127.0.0.1:3333;
}
```
After this you can access the service running on port `3333` at `http://localhost:8888/yoururl`
2018-04-17 15:39:57 +00:00
You can learn about configuring nginx in [this](https://www.digitalocean.com/community/tutorials/understanding-the-nginx-configuration-file-structure-and-configuration-contexts) handy little tutorial.
### supervisor
2018-04-17 16:04:59 +00:00
In most Docker conainers there is a single process running (it gets `PID 1`).
Using TFW you can run as many processes as you want to using supervisord.
2018-04-17 16:04:59 +00:00
Any `.conf` files in the `solvable/supervisor/` directory will be included in the supervisor configuration.
2018-04-17 15:39:57 +00:00
The programs you define this way are easy to manage (starting/stopping/restarting) using the `supervisorctl` command line tool or our built-in event handler.
2018-04-17 16:04:59 +00:00
You can even configure your processes to start with the container by including `autostart=true` in your configuration file.
2018-04-17 15:39:57 +00:00
To run your own webservice for instance you need to create a config file in `solvable/supervisor/` similar to this one:
2018-04-18 08:49:10 +00:00
```text
[program:yourprogram]
user=user
directory=/home/user/example/
command=python3 server.py
autostart=true
```
2018-04-17 16:04:59 +00:00
This starts the `/home/user/example/server.py` script using `python3` after your container entered the running state (because of `autostart=true`, supervisor does not start programs by default).
2018-04-17 15:39:57 +00:00
You can learn more about configuring supervisor [here](http://supervisord.org/configuration.html).
### frontend
This is a clone of the `frontend-tutorial-framework` repository with dependencies installed in `solvable/frontend/node_modules`.
2018-04-17 16:04:59 +00:00
You can modify it to fit your needs, but this requires some Angular knowledge (not much at all).
If all you want to do is start a simple web application and send some messages you can mostly skip the Angluar knowledge bit. Refer to the example in this repo.
**TODO: example non-angular webapp**
### src
2018-04-17 16:04:59 +00:00
This folder contains the source code of a server running TFW and an other server running our event handlers.
Note that this is not a part of the framework by any means, these are just simple examples.
2018-04-17 15:39:57 +00:00
2018-04-18 08:49:10 +00:00
```text
2018-04-17 15:39:57 +00:00
solvable/src
├── tfw_server.py tutorial-framework server
├── event_handler_main.py event handlers implemented in python
└── test_fsm.py example FSM
```
The core of the framework is the `TFWServer` class, which is instanciated in `tfw_server.py`.
2018-04-17 16:04:59 +00:00
This class handles the forwarding of the messages from the frontend to the event handlers connecting to it via ZMQ.
It also manages the FSM.
2018-04-17 15:39:57 +00:00
As you can see this file is set up to start with the container in `solvable/supervisor/tfw_server.conf`.
`event_handler_main.py` contains example usage of our pre-defined event handlers written in Python3.
As you can see they run in a separate process (set up in `solvable/supervisor/event_handlers.conf`).
These event handlers could be implemented in any language that has ZMQ bindings.
## Baby steps
When creating your own challange the process should be something like this:
1. Using our install script to bootstrap your dev environment
2. Creating an FSM that describes your challenge
2018-04-17 16:04:59 +00:00
- An example is in `solvable/src/test_fsm.py`
2018-04-17 15:39:57 +00:00
3. Creating a `TFWServer` instance and setting it up to run:
- Creating a server app: `solvable/src/tfw_server.py`
- Setting it up to run: `solvable/supervisor/tfw_server.conf`
4. Creating event handlers connecting to the `TFWServer` handling events you want to handle:
- Creating an event handler server: `solvable/src/event_handler_main.py`
- Setting it up to run: `solvable/supervisor/event_handlers.conf`
5. Modifying the frontend in `solvable/frontend` to fit your challenge
- This usually involves using our pre-made components
- And perhaps doing some of your own stuff, like:
2018-04-17 16:04:59 +00:00
- Sending messages then handling these in event handlers written in step 4
2018-04-17 15:39:57 +00:00
- Sending triggers to step the FSM
2018-04-18 08:49:56 +00:00
- Including images of cats http://thecatapi.com