# Table of contents
- [Table of contents](#table-of-contents)
- [System Prerequisites](#system-prerequisites)
- [Docker Login](#docker-login)
- [Potential Errors](#potential-errors)
- [Repository `testing-environment`](#repository-testing-environment)
- [Repository `k3k-controller`](#repository-k3k-controller)
- [`config.toml`](#configtoml)
- [Details in `config.toml`](#details-in-configtoml)
- [Potential Errors for Config](#potential-errors-for-config)
- [Diesel](#diesel)
- [Potential Errors for Postgres](#potential-errors-for-postgres)
- [Keycloak: Set up a Local Instance](#keycloak-set-up-a-local-instance)
- [Run `cargo run` Command](#run-cargo-run-command)
- [Notes for `cargo run` on OS X](#notes-for-cargo-run-on-os-x)
- [Potential Errors for `cargo run`](#potential-errors-for-cargo-run)
## System Prerequisites
The pre-requisites for starting the `k3k-controller` locally includes:
- Install `Rust`
- Run `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
- Or use your package manager
- Install `docker` and `docker compose` (e.g. [on Ubuntu][docker_on_ubuntu])
- Run [post-installation steps for Docker][docker_post_install]
- Install build essentials for your system via your package manager
- Example: `sudo apt-get install build-essential` for Debian/Ubuntu)
- Install `postgresql` and `libpq-dev` via your package manager
- Note: For OS X, use `brew install libpq` to install `libpq` instead of `libpq-dev`
## Docker Login
Make sure to generate an access token on [Gitlab][access-token-page] and login to our Docker repository with your username and the key.
You should only need to select `read_registry` and `write_registry` for the scope of your access token.
Login via Docker by:
```sh
$ docker login git.opentalk.dev:5050 -u [token name] -p [token key]
# Example:
# docker login git.opoentalk.dev:5050 -u n.kang -p MYACCESSTOKEN
```
### Potential Errors
<details>
<summary>Error: permission denied</summary>
<p></p>
If you run into `permission denied` issue:
```
$ sudo groupadd docker
$ sudo usermod -aG docker $USER
$ sudo chmod 666 /var/run/docker.sock
```
</details>
## Repository `testing-environment`
Run the following command would spin up all the dependent services:
```
$ docker-compose up -d
# Or use the following to see full logs as docker composes:
$ docker-compose up
```
This assumes that you are using a staging `Keycloak` instance.
If you need to use a local `Keycloak` instance, see [Keycloack: Local Instance](#Keycloak-Local-Instance) for more information.
## Repository `k3k-controller`
Generally speaking, after starting all the required services in [`testing-environment`](#Repository-testing-environment) with `docker-compose`, running the following command in the root project directory for `k3k-controller` would spin up the controller:
```
$ cargo run
```
However, for first-time users, there are additional steps to perform before you can run the controller.
### `config.toml`
First, `k3k-controller` repository comes with an `extra/example.toml` file.
Inside the `k3k-controller` directory, run:
```
$ cp extra/example.toml ./config.toml
```
Some important term clarifications:
- `keycloak`: Open source tool for OIDC authentication (think `OneLogin`, etc.)
- `minio`: Open source object storage (think `S3`)
Below is a fully-working example of `config.toml` without comments and with the most common fields filled for first-time users to get the server running. This example ignores many other fields such as `[logging]`. For a complete example, refer to `extra/example.toml` in [the repository][example-config-toml].
```toml
[database]
# URL used to connect to a postgres.
url = "postgres://postgres:password123@localhost:5432/k3k"
[http]
# The port to bind the HTTP Server to (defaults to 11311).
port = 8000
# URLs that requests are allowed from. Leave empty to allow all.
cors.allowed_origin = ["http://localhost:8080", "http://localhost:8111", "http://localhost:3000", "https://p01nc.heinlein-video.de"]
[keycloak]
# URL to the keycloak
base_url = "https://p01nc.heinlein-video.de:8443/auth"
# Name of the keycloak realm
realm = "K3K"
# Client ID
client_id = "Controller"
# Client secret (application requires confidential client).
client_secret = "ASK-A-COLLEAGUE-FOR-THIS"
[room_server]
# Maximum bitrate allowed for media sessions that will be used to transmit webcam video/audio
# Example: 1.5 Mbit/s
max_video_bitrate = "1500000"
# Maximum bitrate allowed for media sessions used for screen share
# Example: 1MB/s
max_screen_bitrate = "8000000"
[[room_server.connections]]
to_routing_key = "to-janus"
exchange = "janus-exchange"
from_routing_key = "from-janus"
# MinIO configuration
[minio]
# The URI to the MinIO instance
uri = "http://localhost:9555"
# Name of the bucket
# The bucket has to be created manually before starting the controller
bucket = "controller"
# Access key for the MinIO bucket
access_key = "minioadmin"
# Secret key for the MinIO bucket
secret_key = "minioadmin"
```
#### Details in `config.toml`
There are a few details to pay attention to.
<details>
<summary>CORS specification</summary>
<p></p>
Specify an HTTP port for the controller and update the CORS list:
```toml
[http]
port = 8000
cors.allowed_origin = ["http://localhost:8080", "http://localhost:8111", "http://localhost:3000", "https://p01nc.heinlein-video.de"]
```
</details>
<details>
<summary>MinIO Specification</summary>
<p></p>
The `minio` section should look like:
```toml
# fix config.toml minio section (which is a copy of extra/example.toml)
bucket = "controller"
# Access key for the MinIO bucket
access_key = "minioadmin"
# Secret key for the MinIO bucket
secret_key = "minioadmin"
```
</details>
<details>
<summary>Keycloak Specification</summary>
<p></p>
The `keycloak` section has the following `base_url` key-value pair, which points to the correct staging `Keycloak` instance:
```yaml
[keycloak]
# URL to the keycloak
base_url = "https://p01nc.heinlein-video.de:8443/auth"
```
You can also set up `keycloak` locally. See [below](#Keycloak-Local-Instance).
</details>
<br>
#### Potential Errors for Config
<details>
<summary>Cannot find configured MinIO bucket</summary>
<p></p>
If incorrect information is filled in `minio` section, you will encounter `Cannot find configured MinIO bucket` error.
The `minio` section should look like:
```toml
# fix config.toml minio section (which is a copy of extra/example.toml)
bucket = "controller"
# Access key for the MinIO bucket
access_key = "minioadmin"
# Secret key for the MinIO bucket
secret_key = "minioadmin"
```
</details>
<details>
<summary>Failed to initialize OIDC Context</summary>
<p></p>
If incorrect information is filled in `keycloak` section, you will encounter `Failed to initialize OIDC Context` error.
Make sure that the `keycloak` section has the following `base_url` key-value pair, which points to the correct staging `Keycloak` instance:
```toml
[keycloak]
# URL to the keycloak
base_url = "https://p01nc.heinlein-video.de:8443/auth"
```
</details>
<br>
### Diesel
Before we can start the server, we must install `diesel_cli`. Follow the steps listed in [`DB_MIGRATIONS.md`][DB_MIGRATIONS.md]. Specifically, run the following command (which can be found in the notes of the `DB_MIGRATIONS.md` file):
```sh
# Install rustfmt first
$ rustup component add rustfmt
# Install diesel
$ cargo install diesel_cli --version 1.4.1 --no-default-features --features="barrel-migrations,barrel/pg,postgres"
```
#### Potential Errors for Postgres
<details>
<summary>lpq linker with cc failed error</summary>
<p></p>
If you encounter an error with `lpq linker with cc failed error`, fix it by installing `libpq-dev` client for Postgres on your corresponding operating system. For instance, the following steps are for Debian/Ubuntu:
```sh
# Linux
sudo apt-get install libpq-dev
# OS X
brew install libpq
```
</details>
### Keycloak: Set up a Local Instance
Sometimes we might want to spin up keycloak locally.
To do so, go into the `testing-environment` directory and remove the `depends_on: postgres` field in the OIDC compose file `docker-compose.oidc.yaml` might help spin up `Keycloak` locally since the `postgres` service is most likely spinned up already in [repository: `testing-environment`](#Repository-testing-environment) already:
```sh
$ docker-compose -f docker-compose.oidc.yaml up -d
```
On the Keycloak web UI (`user: admin`, `password: admin`), choose the `K3K` realm instead of the `Master` realm.
Then inside the `clients`, choose `controller` and copy the client secret.
Copy the controller client secret from the local `Keycloak` instance and paste into `config.toml` (might need to change realm name in config too).
```yaml
[keycloak]
# URL to the keycloak
base_url = "http://localhost:8080/auth"
# Name of the keycloak realm
realm = "K3K"
# Client ID
client_id = "Controller"
# Client secret (application requires confidential client).
client_secret = "SOME_SECRET_YOU_COPIED_FROM_KEYCLOAK_WEB_UI"
```
Note that Keycloak is a separate service from the `controller`, so the base URL should use a different port like `8080` instead of the `controller`'s port (`8000` in this case).
### Run `cargo run` Command
Now, run `cargo run` again should work and start the controller:
```sh
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.34s
Running `target/debug/k3k-controller`
2022-11-18T12:11:56.615683Z INFO k3k_controller_core: Starting K3K Controller
2022-11-18T12:11:56.858477Z INFO init: k3k_controller_core::storage: Using MinIO S3 bucket: controller
2022-11-18T12:11:57.062099Z WARN k3k_protocol: Skipping the Protocol module as no etherpad is specified in the config
2022-11-18T12:11:57.062252Z WARN k3k_whiteboard: Skipping the Whiteboard module as no spacedeck is specified in the config
2022-11-18T12:11:57.116181Z INFO k3k_controller_core: Making sure the default permissions are set
2022-11-18T12:11:57.159478Z INFO k3k_controller_core: Startup finished
```
#### Notes for `cargo run` on OS X
In case you are using the new M1 chip with OS X, ensure that the following is added to `k3k-controller/.cargo/config` ([solution found here](https://github.com/rust-lang/rust/issues/86658#issuecomment-983925155)):
```
[target.aarch64-apple-darwin]
rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]
```
Once you run have other necessary steps set up, running `cargo run` should spin up the BE server.
#### Potential Errors for `cargo run`
<details>
<summary>Failed to create session: Timeout</summary>
<p></p>
Sometimes, `janus` might crash with a `timeout`:
```sh
# k3k-controller/
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.33s
Running `target/debug/k3k-controller`
2022-11-18T12:10:40.847331Z INFO k3k_controller_core: Starting K3K Controller
2022-11-18T12:10:41.084515Z INFO init: k3k_controller_core::storage: Using MinIO S3 bucket: controller
2022-11-18T12:11:11.345361Z ERROR k3k_controller_core: Crashed with error: Failed to create mcu client
Caused by:
Failed to create session, Timeout
```
This is because `Janus` might have a racing condition problem with `Keycloak`. This can be easily fixed by simply restarting the `janus` service inside `testing-environment` directory:
```sh
$ docker-compose restart janus
```
</details>
[access-token-page]: https://git.opentalk.dev/-/profile/personal_access_tokens
[DB_MIGRATIONS.md]: https://git.opentalk.dev/opentalk/k3k-controller/-/blob/main/DB_MIGRATIONS.md
[docker_on_ubuntu]: https://docs.docker.com/engine/install/ubuntu/
[docker_post_install]: https://docs.docker.com/engine/install/linux-postinstall/
[example-config-toml]: https://git.opentalk.dev/opentalk/k3k-controller/-/blob/main/extra/example.toml