gluon-qemu-testlab 0.0.5
Python scripts to run qemu and gluon based virtual mesh networks
Requires Python: >=3.6

# gluon-qemu-testlab

The *gluon-qemu-testlab* (formerly known as *pynet*) tool helps
in creating virtual mesh topologies
with gluon firmwares using the qemu virtualization
technology. It provides a simple language, where you can
build your topology file in. You can create nodes by
simply calling a function `Node()` and connect them by
calling the `connect()` function. Then gluon-qemu-testlab
does the rest:

1. It starts a qemu instance for each node by using the `image.img` firmware image from the root of the project directory.
2. It connects nodes together as expected using qemus network capabilities.
3. It configures the node though the *config mode* of gluon using an ssh session.
4. Shell accesses to the different nodes and clients is provided.

![picture of random mesh generated by pynet](mesh.gif)

## Requirements

- Linux OS
- At least python3.6
- qemu
- python lib asyncssh

``` shell
pacman -S qemu tmux python python-pip
pip install -r requirements.txt
```

## Quickstart

``` shell
sh update_image.sh                                      # download an image
sudo python36 scenarios/chain_4_nodes.py --run-forever  # start a scenario
```

## Example scenario

Here we connect three nodes in a chain. The syntax is
standard python syntax.
```
#!/usr/bin/env python3
import sys
sys.path.append(".")
from pynet import *

a = Node()
b = Node()
c = Node()

connect(a, b)
connect(b, c)

start()
# tests could go here
finish()
```

### Testing API

``` python
stdout = node.succeed("cmd")                   # execute cmd via ssh and exit with failure if the command
                                               # returns with non-zero exit status

stdout = node.wait_until_succeeds("cmd")       # retry executing cmd via ssh until it suceeds or timeouts

status, stdout = node.execute("cmd")           # execute command via ssh and return the status code in
                                               # addition to stdout

process = node.execute_in_background("cmd")    # start a command in background (e.g. a server process)
process.close()                                # send SIGINT to the command and wait until it exits.
```

### CLI

This CLI options currently exist:
- `--run-forever`
- `--run-tests-on-existing-instance`

Because starting up the qemu instances takes some time, the iteration process during test development can become
tedious. The `--run-tests-on-existing-instance` switch is especially helpful here. You can start one instance of pynet
using the `--run-forever` switch and then invoke scenarios using the `--run-tests-on-existing-instance` switch. This 
new pynet instances will not run their own qemus instances but reuse the already spawned ones. 

### SSH Access

During config mode, the ssh instances are available from the host machine at port `localhost:22001`, `localhost:22002`,
and so on. When the instances are configured, they are available on ports `localhost:22101`, `localhost:22102`, and
so on.

When they are configured, you can use the symlinked scripts:
- `ssh/node1.sh`
- `ssh/node2.sh`
- ...

to easily access the nodes. They provide a little more convinience as they disable known hosts checks.

## Advanced gimmics

- Nodes support resolving names of each other. ```ping node1```
- Nodes also support this command for bat-hosts. ```batctl tr node2```
- To manage ssh connections, pynet automatically generates an rsa key, which is added into the image during config mode.

### set fastd secret

``` python
node.set_fastd_secret('e88b6e7adf88ffb9448293ab008f2fde9a06d012973b7a73cb4947781f6020f2')
```

#### currently disabled features:
- Client namespaces using network namespaces.
- Spawing firefox as a client of a router is also possible. This is very helpful to see the statuspage of a router. Please note, that the shells opened by pynet are root shells. So if you directly start firefox inside such a shell, it has root access.