Implement dockerized building and running of CGW

- Use special build-env docker image that uses local project
  directory (volume mount) to speedup build.
- Implement cgw-img (docker image) generation.
- Track cgw-img tag based on commit.

Signed-off-by: Oleksandr Mazur <oleksandr.mazur@plvision.eu>
This commit is contained in:
Oleksandr Mazur
2024-04-01 22:04:22 +03:00
parent ac7e2f3a5b
commit c3172eed34
4 changed files with 123 additions and 20 deletions

20
Dockerfile Normal file
View File

@@ -0,0 +1,20 @@
FROM rust:1.77.0 as builder
LABEL Description="OpenLan CGW (Build) environment"
WORKDIR /usr/src/openlan-cgw
RUN rustup target add x86_64-unknown-linux-gnu
RUN apt-get update -q -y && apt-get install -q -y \
pkg-config \
build-essential \
cmake \
protobuf-compiler \
libssl-dev
CMD ["make", "-C", "/usr/src/openlan-cgw", "cgw-app"]
FROM busybox:glibc as cgw-img
COPY --from=builder /lib/x86_64-linux-gnu/ /lib/x86_64-linux-gnu/
COPY output/bin/ucentral-cgw /usr/local/bin/ucentral-cgw
CMD ["ucentral-cgw"]

View File

@@ -1,19 +1,68 @@
app_name := ucentral-cgw
.ONESHELL:
SHELL = /bin/bash
.SHELLFLAGS += -e
all: output/bin/${app_name}
@echo "uCentral CGW build app done"
CGW_IMG_ID := openlan-cgw-img
CGW_IMG_TAG := $(shell \
if [[ `git status --porcelain --untracked-files=no` ]]; then \
echo "`git rev-parse --short HEAD`-dirty"; \
else \
echo "`git rev-parse --short HEAD`"; \
fi)
CGW_IMG_CONTAINER_NAME := "openlan_cgw"
clean:
rm -rf ./output/
CGW_BUILD_ENV_IMG_ID := openlan-cgw-build-env
CGW_BUILD_ENV_IMG_TAG := $(shell cat Dockerfile | sha1sum | awk '{print substr($$1,0,11);}')
run: output/bin/${app_name}
./run_cgw.sh
CGW_BUILD_ENV_IMG_CONTAINER_NAME := "cgw_build_env"
# TODO: replace this find with actual --out-dir for cargo
# however, as of now it's an unstable flag, hence gotta do it
# in a bash-ish way.
output/bin/${app_name}:
@rm output/bin/${app_name} || true;
@mkdir output/bin || true;
@cargo build --target-dir ./output &&\
find ./output/ -name "${app_name}" -exec cp {} ./output/bin/ -f \;
.PHONY: all cgw-app cgw-build-env-img cgw-img stop clean run
all: cgw-build-env-img cgw-img
@echo "uCentral CGW build app (container) done"
# Executed inside build-env
cgw-app:
cargo build --target x86_64-unknown-linux-gnu --release
# Builds build-env image itself
cgw-build-env-img:
@echo "Trying to build build-env-img, looking if exists.."
@docker inspect --type=image ${CGW_BUILD_ENV_IMG_ID}:${CGW_BUILD_ENV_IMG_TAG} >/dev/null 2>&1 || \
(echo "build-env-img doesn't exist, building..." && \
docker build --file Dockerfile \
--tag ${CGW_BUILD_ENV_IMG_ID}:${CGW_BUILD_ENV_IMG_TAG} \
--target builder \
.)
@echo "build-env-img build done"
# Generates both build-env img as well as CGW result docker img
# Uses local FS / project dir for storing cache for build etc
cgw-img: stop cgw-build-env-img
@mkdir -p output/bin > /dev/null 2>&1 || true
@docker run -it --name ${CGW_BUILD_ENV_IMG_CONTAINER_NAME} --network=host \
-v `realpath ./`:/usr/src/openlan-cgw \
${CGW_BUILD_ENV_IMG_ID}:${CGW_BUILD_ENV_IMG_TAG}
@docker cp ${CGW_BUILD_ENV_IMG_CONTAINER_NAME}:/usr/src/openlan-cgw/target/x86_64-unknown-linux-gnu/release/ucentral-cgw ./output/bin
@docker build --file Dockerfile \
--tag ${CGW_IMG_ID}:${CGW_IMG_TAG} \
--target cgw-img \
.
@echo Docker build done;
stop:
@echo "Stopping / removing container ${CGW_IMG_CONTAINER_NAME}"
@docker stop ${CGW_IMG_CONTAINER_NAME} > /dev/null 2>&1 || true;
@docker container rm ${CGW_IMG_CONTAINER_NAME} > /dev/null 2>&1 || true;
@echo "Stopping / removing container ${CGW_BUILD_ENV_IMG_CONTAINER_NAME}"
@docker stop ${CGW_BUILD_ENV_IMG_CONTAINER_NAME} > /dev/null 2>&1 || true;
@docker container rm ${CGW_BUILD_ENV_IMG_CONTAINER_NAME} > /dev/null 2>&1 || true;
clean: stop
@echo Cleaning build env and artifacts...
@docker rmi ${CGW_IMG_ID}:${CGW_IMG_TAG} >/dev/null 2>&1 || true
@docker rmi ${CGW_BUILD_ENV_IMG_ID}:${CGW_BUILD_ENV_IMG_TAG} >/dev/null 2>&1 || true
@echo Done!
run: stop cgw-img
@./run_cgw.sh "${CGW_IMG_ID}:${CGW_IMG_TAG}" ${CGW_IMG_CONTAINER_NAME}

View File

@@ -9,8 +9,27 @@ while others are required to be running for the CGW to operate.
CGW utilizes gRPC to communicate with other CGW instances (referred to as Shards). This functionality does not depend on some external thirdparty services.
## Kafka
CGW uses Kafka as a main North-Bound API layer for communication with NB services. CnC topic is used for commands and requests handling, CnC_Res is used to send replies/results back (CGW reads CnC and writes into CnC_Res).
### Requirements
It's required for the Kafka to have the following topics premade upon CGW launch:
## PSQL
Application utilizes relational DB (PSQL) to store registered Infrastructure Groups as well as registered Infrastructures.
### Requirements
1. It's required for the PSQL to have the following tables premade upon CGW launch:
```
CREATE TABLE infrastructure_groups
(
id INT PRIMARY KEY,
reserved_size INT,
actual_size INT
);
CREATE TABLE infras
(
mac MACADDR PRIMARY KEY,
infra_group_id INT,
FOREIGN KEY(infra_group_id) REFERENCES infrastructure_groups(id) ON DELETE CASCADE
);
```
2. Default user 'cgw' and password '123' is assumed, but it can be changed through the env variables.
## Redis
fast in-memory DB that CGW uses to store all needed runtime information (InfraGroup assigned CGW id, remote CGW info - IP, gRPC port etc)
# Building
@@ -20,12 +39,20 @@ Key and certificate will be used by the CGW internally to validate incoming WSS
```console
$ make all
```
The output (CGW binaries) is then put into the ./output directory.
The output (CGW binaries) is then put into the ./output/bin directory.
Two new docker images will be generated on host system:
**openlan_cgw** - image that holds CGW application itself
**cgw_build_env** - building enviroment docker image that is used for generating openlan_cgw
# Running
The following script can be used to launch the CGW app
```console
$ make run
```
Command creates and executed (starts) docker container name 'openlan_cgw'
To stop the container from running (remove it) use the following cmd:
```console
$ make stop
```
Running application with default arguments might not be desired behavior.
And thus the run script utilizes the following list of *enviroment* variables that you can define before running it to alternate behavior of the app.
The following list is a list of enviroment variables you can define to configure cgw-app behavior in certain way:
@@ -38,6 +65,8 @@ CGW_KAFKA_IP - IP of remote KAFKA server to connect to (NB API)
CGW_KAFKA_PORT - PORT of remote KAFKA server to connect to
CGW_DB_IP - IP of remote database server to connect to
CGW_DB_PORT - PORT of remote database server to connect to
CGW_DB_USER - PSQL DB username (credentials) to use upon connect to DB
CGW_DB_PASS - PSQL DB password (credentials) to use upon connect to DB
CGW_REDIS_DB_IP - IP of remote redis-db server to connect to
CGW_REDIS_DB_PORT - PORT of remote redis-db server to connect to
CGW_LOG_LEVEL - log level to start CGW application with (debug, info)
@@ -48,6 +77,9 @@ Example of properly configured list of env variables to start CGW:
$ export | grep CGW
declare -x CGW_DB_IP="172.20.10.136" # PSQL server is at xxx.136
declare -x CGW_DB_PORT="5432"
declare -x CGW_DB_USERNAME="cgw" # PSQL login credentials (username) default 'cgw' will be used
declare -x CGW_DB_PASS="123" # PSQL login credentials (password) default '123' will be used
declare -x CGW_DB_IP="172.20.10.136" # PSQL server is at xxx.136
declare -x CGW_GRPC_IP="172.20.10.153" # local default subnet is 172.20.10.0/24
declare -x CGW_GRPC_PORT="50051"
declare -x CGW_ID="1"
@@ -59,4 +91,4 @@ declare -x CGW_WSS_IP="0.0.0.0" # accept WSS connections at all inter
declare -x CGW_WSS_PORT="15002"
```
# Certificates
<TBD>
TBD

View File

@@ -27,6 +27,8 @@ KAFKA_IP="${CGW_KAFKA_IP:-$DEFAULT_KAFKA_IP}"
KAFKA_PORT="${CGW_KAFKA_PORT:-$DEFAULT_KAFKA_PORT}"
DB_IP="${CGW_DB_IP:-$DEFAULT_DB_IP}"
DB_PORT="${CGW_DB_PORT:-$DEFAULT_DB_PORT}"
DB_USR="${CGW_DB_USER:-cgw}"
DB_PASS="${CGW_DB_PASS:-123}"
REDIS_DB_IP="${CGW_REDIS_DB_IP:-$DEFAULT_REDIS_DB_IP}"
REDIS_DB_PORT="${CGW_REDIS_DB_PORT:-$DEFAULT_REDIS_DB_PORT}"
LOG_LEVEL="${CGW_LOG_LEVEL:-info}"
@@ -40,12 +42,12 @@ echo "KAFKA: $KAFKA_IP:$KAFKA_PORT"
echo "DB: $DB_IP:$DB_PORT"
echo "REDIS_DB: $REDIS_DB_IP:$REDIS_DB_PORT"
# TBD: docker-based run
# TBD 2: add num of thread cfg (start argument)
output/bin/ucentral-cgw -w 4 -c $ID \
# TBD: add num of thread cfg (start argument)
docker run -d -t --network=host --name $2 $1 ucentral-cgw \
--grpc-ip $GRPC_IP --grpc-port $GRPC_PORT \
--wss-ip $WSS_LOCAL_IP --wss-port $WSS_LOCAL_PORT \
--kafka-ip $KAFKA_IP --kafka-port $KAFKA_PORT \
--db-ip $DB_IP --db-port $DB_PORT \
--db-username $DB_USR --db-password $DB_PASS \
--redis-db-ip $REDIS_DB_IP --redis-db-port $REDIS_DB_PORT \
$LOG_LEVEL