1
0
mirror of https://github.com/avatao-content/test-tutorial-framework synced 2024-07-03 22:08:46 +00:00
Go to file
2018-04-17 17:39:57 +02:00
controller Initial commit, first version of test TFW project 2018-03-23 15:27:42 +01:00
hack Unify script headers 2018-04-16 20:47:23 +02:00
solvable Unify nginx configuration style 2018-04-17 15:15:01 +02:00
.dockerignore Add .dockerignore to avoid choking poor Docker on JS crapware 2018-03-31 20:00:49 +02:00
config.yml Update project to comply user separation 2018-04-04 17:44:14 +02:00
README.md Continue writing docs 2018-04-17 17:39:57 +02: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.

Getting started with creating challenges using the framework setting up a development environment, building, running and such is documented here.

Setting up a development environment

Just copy and paste the following command in a terminal:

bash -c "$(curl -fsSL https://git.io/vxBfj)"

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

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:

your_repo
├── solvable
│   └── [TFW based Docker image]
├── controller
│   └── [solution checking]
├── metadata
│   └── [challenge descriptions, writeups, etc.]
└── config.yml

The only notable difference is that the solvable Docker image is a child image 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:

solvable
├── Dockerfile
├── nginx        webserver configurations
├── supervisor   process manager (init replacement)
├── frontend     clone of the frontend-tutorial-framework repo with dependencies installed
└── src          challenge source code

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.

The src directory is not a concept of TFW and you can call it however you like and put it's contens anywhere, just be sure to adjust your Dockerfile accordingly.

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.

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. This is really easy: just create a config file in solvable/nginx/ similar to this one:

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

You can learn about configuring nginx in this handy little tutorial.

supervisor

In most Docker conainers there is a single running process with PID 1. Using TFW you can run as many processes as you want to using supervisord.

Any .conf files in the solvable/supervisor/ will be included in the supervisor configuration. 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. You can even configure your processes to start with the container by including autostart=true in the configuration file.

To run your own webservice for instance you need to create a config file in solvable/supervisor/ similar to this one:

[program:yourprogram]
user=user
directory=/home/user/example/
command=python3 server.py
autostart=true

This starts the /home/user/example/server.py script using python3 after your container entered the running state (because of autostart=true).

You can learn more about configuring supervisor here.

frontend

This is a clone of the frontend-tutorial-framework repository with dependencies installed in solvable/frontend/node_modules.

src

This folder contains the source code of the challenge.

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. This class handles the forwarding of the messages from the frontend to the event handlers connecting to it via ZMQ and manages the FSM. 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
    • This is done in solvable/src/test_fsm.py
  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:
      • Sending messages then handling these in event handlers
      • Sending triggers to step the FSM