Skip to content

Commit

Permalink
feat: makefile for automating builds and deployments for dev environm…
Browse files Browse the repository at this point in the history
…ents (#646)

Co-authored-by: Patricia Reinoso <[email protected]>
Co-authored-by: Bartlomiej Gmerek <[email protected]>
  • Loading branch information
3 people authored Oct 28, 2024
1 parent 4277cf7 commit 7fb6ce8
Show file tree
Hide file tree
Showing 5 changed files with 257 additions and 37 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

# production
/build
/webconsole-src
/artifacts

# misc
.DS_Store
Expand All @@ -37,4 +39,9 @@ upf_config.json
*.tsbuildinfo
next-env.d.ts

# ide
*.idea
*.rock

# binaries
webconsole
102 changes: 65 additions & 37 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,51 @@
# Contributing

NMS is the frontend code for SD-Core's [`Webconsole`](https://github.com/omec-project/webconsole/).
It is based on the [`Next.js`](https://nextjs.org/) React framework. In order to produce the final
binary that will be used to serve the frontend for SD-Core, we statically export the project in this repository, embed it in the `Webconsole` application, and build the project together. The final webserver
binary is the output of `Webconsole`'s build command.

Since we only rely on the static export, this means that running the common `npm run dev` script may produce unusual behaviour that doesn't exist in a deployed build. It also means that the project does not use any of Nextjs's server based features which can be found [here](https://nextjs.org/docs/app/building-your-application/deploying/static-exports#unsupported-features).

## Development

To make contributions to this project, make sure you have [`Nodejs 18`](https://nodejs.org/) installed.
We use a makefile to build and deploy the project. It has targets that will help with development. You can read more about what the makefile does in the [`Build`](#build) section below.

### `make webconsole`

This target will produce the webconsole binary with the static export of NMS embedded as its frontend.

`go` and `nodejs` must be installed to use this option.

### `make rock`

1. Clone the repository:
This target will produce a `sdcore-nms.rock` OCI image file, which will have the webconsole binary as a service.

```shell
git clone [email protected]:canonical/sdcore-nms.git
```
`rockcraft` must be installed to use this option.

2. Navigate to the project directory:
### `make deploy`

```shell
cd sdcore-nms
```
This target will create an LXC VM called `nms`, install docker, deploy the `NMS` and `MongoDB` OCI image, create a valid config file for `NMS`, and start the program.
After the process is done, from your host machine you can run `lxc list`, and use the IP address to connect to both mongodb and NMS. The port for NMS is `:5000` and the port for mongodb is `:27017`.

3. Install the dependencies:
`make rock` must have successfully completed and `lxd` must be installed to use this option.

```shell
npm install
```
### `make hotswap`

4. Run the development server:
This target will take the webconsole binary, place it in the `nms` container inside the LXC VM, and restart the pebble service. This is useful for quickly updating the locally deployed NMS program.

```bash
npm run dev
```
`make deploy` must have successfully completed to use this option.

Open [http://localhost:3000](http://localhost:3000) with your browser to view the changes.
### `make logs`

This target will print the last 20 log entries that was produced by the rock, which is the combination of
pebble and webconsole logs.

`make deploy` must have successfully completed to use this option.

### `make clean`

This target will delete the rock, the binary, and destroy the VM.

## Testing

Expand All @@ -45,31 +61,43 @@ npm run lint

## Build

To build the project:
There are 2 targets for building: the `webconsole` binary and the `sdcore-nms.rock` OCI image. The artifacts
for them are stored in the `/artifacts` folder. Any files used in the build process are stored in the `/build` folder.

```shell
npm run build
```
### Webconsole binary

## Container image
`go` and `nodejs` is required to build webconsole.

Pack the rock
The `make webconsole` target is responsible for producing the binary that serves the NMS frontend. Once run, it will:

```bash
sudo snap install rockcraft --edge --classic
rockcraft pack -v
```
1. Clone the `omec-project/webconsole` repository into `build/webconsole-src`
2. Install the frontend dependencies by running `npm install`
3. Generate the static frontend files by running `npm run build`
4. Move the frontend files into `build/webconsole-src/ui/frontend_files`
5. Build the webconsole binary by running `go build --tags ui -o webconsole ./server.go`

Move the rock to Docker's registry
The binary will need to be run with a config file. An example is available in the `examples/config` folder.

```bash
sudo rockcraft.skopeo --insecure-policy copy oci-archive:sdcore-nms_0.2.0_amd64.rock docker-daemon:sdcore-nms:0.2.0
```
### OCI image

Run the NMS
`rockcraft` is required to create the OCI image.

```bash
docker run -p 3000:3000 sdcore-nms:0.2.0
```
The rock can be built with `rockcraft pack`. This process will use the local NMS and a predefined tag of webconsole repo to create an OCI image. The webconsole branch/tag is defined in the `rockcraft.yaml` file.

The `make rock` target modifies this build process by directly using the `build/webconsole-src` directory. This allows you to use a local version of webconsole in the OCI image instead of having to pull from the specified tag in `rockcraft.yaml`. This is useful if you want to test changes to the backend rather than the frontend. The process is:

1. Modify the `rockcraft.yaml` to use `build/webconsole-src`
2. Run `rockcraft pack`
3. Restore the original `rockcraft.yaml`

## Deploy

The binary requires a config file and an available mongodb deployment to operate. By default, the path for the config file is `./config/webuicfg.yaml` from the directory of the binary. The OCI image does not come with a config file preconfigured, but the repo contains an example at `examples/config/webuicfg.yaml`.

`make deploy` takes care of quickly getting a running program. It will:

You will have the NMS available in `http://localhost:3000`.
1. Create a VM in LXD called `nms`
2. Install docker and skopeo in the VM
3. Load the `sdcore-nms.rock` OCI image and pull the `mongodb:noble` image into the local registry.
4. Run both images in docker
5. Load the example config located in `examples/config/webuicfg.yaml` into the `nms` docker image, and restart the program.
101 changes: 101 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
BUILD_FOLDER := build
ARTIFACT_FOLDER := artifacts

WEBCONSOLE_PROJECT_DIR := webconsole-src
WEBCONSOLE_FILES := $(shell find $(BUILD_FOLDER)/$(WEBCONSOLE_PROJECT_DIR) -regex ".*\.go" 2> /dev/null)
WEBCONSOLE_REPO_URL := https://github.com/omec-project/webconsole.git
WEBCONSOLE_ARTIFACT_NAME := webconsole

NMS_FILES := $(shell find app components images utils -type f) package.json package-lock.json
NMS_ARTIFACT_NAME := nms-static

ROCK_ARTIFACT_NAME := sdcore-nms.rock

$(shell mkdir -p $(BUILD_FOLDER))
$(shell mkdir -p $(ARTIFACT_FOLDER))

webconsole: $(ARTIFACT_FOLDER)/$(WEBCONSOLE_ARTIFACT_NAME)
@echo "Built Webconsole with frontend"

rock: $(ARTIFACT_FOLDER)/$(ROCK_ARTIFACT_NAME)
@echo "Built rock with local webconsole"

deploy: rockcraft.yaml
@if [ "$$(lxc list 2> /dev/null | grep nms > /dev/null; echo $$?)" = 1 ]; then \
echo "creating new NMS VM instance in LXD"; \
lxc launch ubuntu:24.04 --vm nms; \
fi
@echo "waiting for the VM to start"
@while [ "$$(lxc info nms 2> /dev/null | grep Processes | grep "\-1" > /dev/null; echo $$?)" = 0 ]; do sleep 2; done
@echo "waiting for the vm to work"
sleep 10
lxc exec nms -- snap install docker --classic
lxc exec nms -- snap install rockcraft --classic
lxc exec nms -- docker pull mongo:noble
@if [ "$$(lxc exec nms -- docker ps 2> /dev/null | grep mongodb > /dev/null; echo $$?)" = 1 ]; then \
echo "creating and running mongodb in Docker"; \
lxc exec nms -- docker run -d \
--name mongodb \
--network host \
mongo:noble; \
fi

lxc file push $(ARTIFACT_FOLDER)/$(ROCK_ARTIFACT_NAME) nms/root/$(ROCK_ARTIFACT_NAME)
lxc file push examples/config/webuicfg.yaml nms/root/
@if [ "$$(lxc exec nms -- docker ps 2> /dev/null | grep nms > /dev/null; echo $$?)" = 0 ]; then \
echo "removing old nms container"; \
lxc exec nms -- docker stop nms; \
lxc exec nms -- docker rm nms; \
fi

lxc exec nms -- rockcraft.skopeo --insecure-policy copy oci-archive:sdcore-nms.rock docker-daemon:nms:latest
lxc exec nms -- docker run -d \
--name nms \
-e WEBUI_ENDPOINT=$$(lxc info nms | grep enp5s0 -A 15 | grep inet: | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}'):5000 \
-v /root/webuicfg.yaml:/config/webuicfg.yaml \
--network host \
nms:latest --verbose
@echo "You can access NMS at $$(lxc info nms | grep enp5s0 -A 15 | grep inet: | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}'):5000"

hotswap: artifacts/webconsole examples/config/webuicfg.yaml
@echo "make: replacing nms binary with new binary"
lxc file push artifacts/webconsole nms/root/
lxc file push examples/config/webuicfg.yaml nms/root/
lxc exec nms -- docker cp ./webconsole nms:/bin/webconsole
lxc exec nms -- docker exec nms pebble restart nms

logs:
lxc exec nms -- docker logs nms --tail 20

clean:
rm -rf $(BUILD_FOLDER)
rm -rf $(ARTIFACT_FOLDER)
-lxc stop nms
-lxc delete nms

$(BUILD_FOLDER)/fetch-repo:
-git clone $(WEBCONSOLE_REPO_URL) $(BUILD_FOLDER)/$(WEBCONSOLE_PROJECT_DIR)
touch $(BUILD_FOLDER)/fetch-repo

$(BUILD_FOLDER)/$(NMS_ARTIFACT_NAME): $(NMS_FILES)
@npm install && npm run build
rm -rf $@
mv out $@

$(ARTIFACT_FOLDER)/$(WEBCONSOLE_ARTIFACT_NAME): $(BUILD_FOLDER)/fetch-repo $(WEBCONSOLE_FILES) $(BUILD_FOLDER)/$(NMS_ARTIFACT_NAME)
rm -rf $(BUILD_FOLDER)/$(WEBCONSOLE_PROJECT_DIR)/ui/frontend_files/*
cp -R $(BUILD_FOLDER)/$(NMS_ARTIFACT_NAME)/* $(BUILD_FOLDER)/$(WEBCONSOLE_PROJECT_DIR)/ui/frontend_files
cd $(BUILD_FOLDER)/$(WEBCONSOLE_PROJECT_DIR) && go build --tags ui -o $(WEBCONSOLE_ARTIFACT_NAME) ./server.go

mv $(BUILD_FOLDER)/$(WEBCONSOLE_PROJECT_DIR)/$(WEBCONSOLE_ARTIFACT_NAME) $@

$(ARTIFACT_FOLDER)/$(ROCK_ARTIFACT_NAME): $(ARTIFACT_FOLDER)/$(WEBCONSOLE_ARTIFACT_NAME) rockcraft.yaml
@echo "make: building oci image with a local version of webconsole"
mv rockcraft.yaml rockcraft_default.yaml
sed "s~source-type.*~~; s~source-tag.*~~; s~source: https.*~source: .\/$(BUILD_FOLDER)/$(WEBCONSOLE_PROJECT_DIR)~" rockcraft_default.yaml > rockcraft.yaml
-rockcraft pack
mv rockcraft_default.yaml rockcraft.yaml
@if [ -n "$$(ls | grep *.rock)" ]; then \
mv $$(ls | grep *.rock) $@; \
fi

78 changes: 78 additions & 0 deletions examples/config/webuicfg.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
configuration:
managedByConfigPod:
enabled: true
syncUrl: ""
mongodb:
name: free5gc
url: mongodb://localhost:27017
spec-compliant-sdf: false
info:
description: WebUI initial local configuration
version: 1.0.0
logger:
AMF:
ReportCaller: false
debugLevel: info
AUSF:
ReportCaller: false
debugLevel: info
Aper:
ReportCaller: false
debugLevel: info
CommonConsumerTest:
ReportCaller: false
debugLevel: info
FSM:
ReportCaller: false
debugLevel: info
MongoDBLibrary:
ReportCaller: false
debugLevel: info
N3IWF:
ReportCaller: false
debugLevel: info
NAS:
ReportCaller: false
debugLevel: info
NGAP:
ReportCaller: false
debugLevel: info
NRF:
ReportCaller: false
debugLevel: info
NamfComm:
ReportCaller: false
debugLevel: info
NamfEventExposure:
ReportCaller: false
debugLevel: info
NsmfPDUSession:
ReportCaller: false
debugLevel: info
NudrDataRepository:
ReportCaller: false
debugLevel: info
OpenApi:
ReportCaller: false
debugLevel: info
PCF:
ReportCaller: false
debugLevel: info
PFCP:
ReportCaller: false
debugLevel: info
PathUtil:
ReportCaller: false
debugLevel: info
SMF:
ReportCaller: false
debugLevel: info
UDM:
ReportCaller: false
debugLevel: info
UDR:
ReportCaller: false
debugLevel: info
WEBUI:
ReportCaller: false
debugLevel: info
6 changes: 6 additions & 0 deletions rockcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ license: Apache-2.0
platforms:
amd64:

services:
nms:
command: webconsole
override: replace
startup: enabled

parts:
nms:
plugin: nil
Expand Down

0 comments on commit 7fb6ce8

Please sign in to comment.