From 82d5c1c0ddc0336d6df809052273a0312603c245 Mon Sep 17 00:00:00 2001 From: ismail Date: Tue, 13 Jul 2021 17:41:06 +0200 Subject: [PATCH 1/2] CI: pipeline for cn5g deployment check based on docker-compose for community Signed-off-by: ismail --- ci-scripts/Jenkinsfile-GitLab-Docker-Check | 224 +++++++++++++++++++++ docker-compose/docker-compose-no-nrf.yaml | 16 +- docker-compose/docker-compose.yaml | 16 +- 3 files changed, 240 insertions(+), 16 deletions(-) create mode 100644 ci-scripts/Jenkinsfile-GitLab-Docker-Check diff --git a/ci-scripts/Jenkinsfile-GitLab-Docker-Check b/ci-scripts/Jenkinsfile-GitLab-Docker-Check new file mode 100644 index 0000000..bae472e --- /dev/null +++ b/ci-scripts/Jenkinsfile-GitLab-Docker-Check @@ -0,0 +1,224 @@ +#!/bin/groovy +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +//------------------------------------------------------------------------------- +// Abstraction function to send social media messages: +// like on Slack or Mattermost +def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) { + if (params.pipelineUsesSlack != null) { + if (params.pipelineUsesSlack) { + slackSend channel: pipeChannel, color: pipeColor, message: pipeMessage + } + } +} + +// Location of the CN executor node +def cn_ci_host = params.Host_CN_CI_Server + +// for lock +def cn_ci_resource = params.DockerContainers + +// When triggered by upstream, specify which tag to use +def upstreamTagToUse = params.upstreamTagToUse + +// Location of the 2nd CN executor +def new_host_flag = false +def new_host = "" +def new_host_user = "" + +// Location of the CN tester +def dsT_host_flag = false +def dsT_host = "" +def dsT_host_user = "" +def dsT_host_ip_addr = "" + +// Flags +def scmEvent = false +def upstreamEvent = false + +//------------------------------------------------------------------------------- +// Pipeline start +pipeline { + agent { + label cn_ci_host + } + options { + disableConcurrentBuilds() + timestamps() + ansiColor('xterm') + lock(cn_ci_resource) + } + stages { + stage ('Verify Parameters') { + steps { + script { + echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' + + JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"' + JOB_TIMESTAMP = JOB_TIMESTAMP.trim() + + if (params.Host_CN_CI_2nd_Server_Flag != null) { + new_host_flag = params.Host_CN_CI_2nd_Server_Flag + if (new_host_flag) { + new_host = params.Host_CN_CI_2nd_Server + new_host_user = params.Host_CN_CI_2nd_Server_Login + echo "1st Node is ${NODE_NAME}" + echo "2nd Node is ${new_host}" + } else { + echo "Node is ${NODE_NAME}" + } + } else { + echo "Node is ${NODE_NAME}" + } + + // Find out the cause of the trigger + for (cause in currentBuild.getBuildCauses()) { + if (cause.toString() ==~ /.*UpstreamCause.*/) { + upstreamEvent = true + } + } + if (upstreamEvent) { + sh "git clean -x -d -f > /dev/null 2>&1" + sh "git fetch --prune > /dev/null 2>&1" + sh 'git checkout -f ' + upstreamTagToUse + } + if ((!upstreamEvent) && (!scmEvent)) { + sh "git clean -x -d -f > /dev/null 2>&1" + } + sh "mkdir -p archives/cn5g" + sh "mkdir -p archives/cn5gwithnoNRF" + } + } + } + stage ('Deploy Whole 5G Core Network with NRF') { + steps { + script { + echo '\u2705 \u001B[32mDeploy CN5G using Docker-Compose with NRF\u001B[0m' + dir('docker-compose') { + sh 'docker-compose -f docker-compose.yaml up -d > ../archives/cn5g/compose_5gcn_up.log 2>&1' + sh 'sleep 100' + // Do a check on number of healthy containers + // 6 == mysql + nrf + amf + smf + upf(spgwu-tiny) + ret = sh returnStdout: true, script: 'docker-compose ps -a | grep -v unhealthy | grep -c healthy || true' + ret = ret.trim() + if (ret != '5') { + error "Deployment went wrong!" + } + } + } + } + post { + always { + script { + sh 'docker logs oai-nrf > archives/cn5g/oai_nrf.log' + sh 'docker logs oai-amf > archives/cn5g/oai_amf.log' + sh 'docker logs oai-smf > archives/cn5g/oai_smf.log' + sh 'docker logs oai-spgwu > archives/cn5g/oai_spgwu.log' + } + } + success { + script { + sh 'echo "DEPLOYMENT: OK"' + } + } + unsuccessful { + script { + sh 'echo "DEPLOYMENT: KO"' + } + } + } + } + stage ('Undeploy 5G-CN with NRF') { + steps { + script { + echo '\u2705 \u001B[32mUn-Deploy CN5G with NRF\u001B[0m' + dir('docker-compose') { + sh 'docker-compose down > ../archives/cn5g/compose_normal_down.log 2>&1' + } + } + } + } + + stage ('Deploy Whole 5G Core Network with no NRF') { + steps { + script { + echo '\u2705 \u001B[32mDeploy CN5G using Docker-Compose with no NRF\u001B[0m' + dir('docker-compose') { + sh 'docker-compose -f docker-compose-no-nrf.yaml up -d > ../archives/cn5gwithnoNRF/compose_5gcn_up.log 2>&1' + sh 'sleep 100' + // Do a check on number of healthy containers + // 5 == mysql + amf + smf + upf(spgwu-tiny) + ret = sh returnStdout: true, script: 'docker-compose ps -a | grep -v unhealthy | grep -c healthy || true' + ret = ret.trim() + if (ret != '4') { + error "Deployment went wrong with no NRF!" + } + } + } + } + post { + always { + script { + sh 'docker logs oai-amf > archives/cn5gwithnoNRF/oai_amf.log' + sh 'docker logs oai-smf > archives/cn5gwithnoNRF/oai_smf.log' + sh 'docker logs oai-spgwu > archives/cn5gwithnoNRF/oai_spgwu.log' + } + } + success { + script { + sh 'echo "DEPLOYMENT: OK with no NRF"' + } + } + unsuccessful { + script { + sh 'echo "DEPLOYMENT: KO with no NRF"' + } + } + } + } + stage ('Undeploy 5G-CN with no NRF') { + steps { + script { + echo '\u2705 \u001B[32mUn-Deploy CN5G with no NRF\u001B[0m' + dir('docker-compose') { + sh 'docker-compose down > ../archives/cn5gwithnoNRF/compose_normal_down.log 2>&1' + } + } + } + } + } + post { + always { + script { + // Remove any leftover containers/networks + dir('docker-compose') { + sh 'docker-compose down' + } + // Zipping all archived log files + sh "zip -r -qq cn5g_deploy_docker_logs.zip archives" + if (fileExists('cn5g_deploy_docker_logs.zip')) { + archiveArtifacts artifacts: 'cn5g_deploy_docker_logs.zip' + } + } + } + } +} diff --git a/docker-compose/docker-compose-no-nrf.yaml b/docker-compose/docker-compose-no-nrf.yaml index 785b689..83ffc25 100644 --- a/docker-compose/docker-compose-no-nrf.yaml +++ b/docker-compose/docker-compose-no-nrf.yaml @@ -195,11 +195,11 @@ networks: external: name: demo-oai-public-net # Incase the user wants docker-compose to create a bridge rather than creating the bridge manually then uncomment the below lines -# public_net: -# driver: bridge -# name: demo-oai-public-net -# ipam: -# config: -# - subnet: 192.168.70.128/26 -# driver_opts: -# com.docker.network.bridge.name: "demo-oai" + public_net: + driver: bridge + name: demo-oai-public-net + ipam: + config: + - subnet: 192.168.70.128/26 + driver_opts: + com.docker.network.bridge.name: "demo-oai" diff --git a/docker-compose/docker-compose.yaml b/docker-compose/docker-compose.yaml index cfb88e4..3b8195a 100644 --- a/docker-compose/docker-compose.yaml +++ b/docker-compose/docker-compose.yaml @@ -215,11 +215,11 @@ networks: external: name: demo-oai-public-net # Incase the user wants docker-compose to create a bridge rather than creating the bridge manually then uncomment the below lines -# public_net: -# driver: bridge -# name: demo-oai-public-net -# ipam: -# config: -# - subnet: 192.168.70.128/26 -# driver_opts: -# com.docker.network.bridge.name: "demo-oai" + public_net: + driver: bridge + name: demo-oai-public-net + ipam: + config: + - subnet: 192.168.70.128/26 + driver_opts: + com.docker.network.bridge.name: "demo-oai" -- GitLab From d7ae0161459d527cd7ea0b8d3f3aa3557510e8c0 Mon Sep 17 00:00:00 2001 From: ismail Date: Wed, 21 Jul 2021 14:12:08 +0200 Subject: [PATCH 2/2] updated to create network brige automatically and also to capture the pcaps Signed-off-by: ismail --- ci-scripts/Jenkinsfile-GitLab-Docker-Check | 32 ++---------------- docker-compose/docker-compose-no-nrf.yaml | 17 +++++++++- docker-compose/docker-compose.yaml | 23 ++++++++++++- docs/CONFIGURE_CONTAINERS.md | 39 +--------------------- docs/DEPLOY_SA5G_WITH_DS_TESTER.md | 35 ++----------------- 5 files changed, 44 insertions(+), 102 deletions(-) diff --git a/ci-scripts/Jenkinsfile-GitLab-Docker-Check b/ci-scripts/Jenkinsfile-GitLab-Docker-Check index bae472e..9900ea9 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Docker-Check +++ b/ci-scripts/Jenkinsfile-GitLab-Docker-Check @@ -37,24 +37,11 @@ def cn_ci_host = params.Host_CN_CI_Server // for lock def cn_ci_resource = params.DockerContainers -// When triggered by upstream, specify which tag to use -def upstreamTagToUse = params.upstreamTagToUse - // Location of the 2nd CN executor def new_host_flag = false def new_host = "" def new_host_user = "" -// Location of the CN tester -def dsT_host_flag = false -def dsT_host = "" -def dsT_host_user = "" -def dsT_host_ip_addr = "" - -// Flags -def scmEvent = false -def upstreamEvent = false - //------------------------------------------------------------------------------- // Pipeline start pipeline { @@ -90,20 +77,7 @@ pipeline { echo "Node is ${NODE_NAME}" } - // Find out the cause of the trigger - for (cause in currentBuild.getBuildCauses()) { - if (cause.toString() ==~ /.*UpstreamCause.*/) { - upstreamEvent = true - } - } - if (upstreamEvent) { - sh "git clean -x -d -f > /dev/null 2>&1" - sh "git fetch --prune > /dev/null 2>&1" - sh 'git checkout -f ' + upstreamTagToUse - } - if ((!upstreamEvent) && (!scmEvent)) { - sh "git clean -x -d -f > /dev/null 2>&1" - } + sh "git clean -x -d -f > /dev/null 2>&1" sh "mkdir -p archives/cn5g" sh "mkdir -p archives/cn5gwithnoNRF" } @@ -117,7 +91,7 @@ pipeline { sh 'docker-compose -f docker-compose.yaml up -d > ../archives/cn5g/compose_5gcn_up.log 2>&1' sh 'sleep 100' // Do a check on number of healthy containers - // 6 == mysql + nrf + amf + smf + upf(spgwu-tiny) + // 5 == mysql + nrf + amf + smf + upf(spgwu-tiny) ret = sh returnStdout: true, script: 'docker-compose ps -a | grep -v unhealthy | grep -c healthy || true' ret = ret.trim() if (ret != '5') { @@ -166,7 +140,7 @@ pipeline { sh 'docker-compose -f docker-compose-no-nrf.yaml up -d > ../archives/cn5gwithnoNRF/compose_5gcn_up.log 2>&1' sh 'sleep 100' // Do a check on number of healthy containers - // 5 == mysql + amf + smf + upf(spgwu-tiny) + // 4 == mysql + amf + smf + upf(spgwu-tiny) ret = sh returnStdout: true, script: 'docker-compose ps -a | grep -v unhealthy | grep -c healthy || true' ret = ret.trim() if (ret != '4') { diff --git a/docker-compose/docker-compose-no-nrf.yaml b/docker-compose/docker-compose-no-nrf.yaml index 83ffc25..88b2d98 100644 --- a/docker-compose/docker-compose-no-nrf.yaml +++ b/docker-compose/docker-compose-no-nrf.yaml @@ -23,6 +23,12 @@ services: oai-amf: container_name: "oai-amf" image: oai-amf:develop + command: > + bash -c "nohup tshark -i eth0 -w /tmp/amf.pcap 2>&1 > /dev/null & + /openair-amf/bin/oai_amf -c /openair-amf/etc/amf.conf -o | tee /tmp/amf.log 2>&1 + " + cap_add: + - NET_ADMIN environment: - TZ=Europe/paris - INSTANCE=0 @@ -88,6 +94,12 @@ services: oai-smf: container_name: "oai-smf" image: oai-smf:develop + command: > + bash -c "nohup tshark -i eth0 -w /tmp/smf.pcap 2>&1 > /dev/null & + /openair-smf/bin/oai_smf -c /openair-smf/etc/smf.conf -o | tee /tmp/smf.log 2>&1 + " + cap_add: + - NET_ADMIN environment: - TZ=Europe/Paris - INSTANCE=0 @@ -131,6 +143,10 @@ services: oai-spgwu: container_name: "oai-spgwu" image: oai-spgwu-tiny:develop + command: > + bash -c "nohup tshark -i eth0 -w /tmp/spgwu.pcap 2>&1 > /dev/null & + /openair-spgwu-tiny/bin/oai_spgwu -c /openair-spgwu-tiny/etc/spgw_u.conf -o | tee /tmp/spgwu.log 2>&1 + " environment: - TZ=Europe/Paris - PID_DIRECTORY=/var/run @@ -194,7 +210,6 @@ networks: public_net: external: name: demo-oai-public-net -# Incase the user wants docker-compose to create a bridge rather than creating the bridge manually then uncomment the below lines public_net: driver: bridge name: demo-oai-public-net diff --git a/docker-compose/docker-compose.yaml b/docker-compose/docker-compose.yaml index 3b8195a..8d85bee 100644 --- a/docker-compose/docker-compose.yaml +++ b/docker-compose/docker-compose.yaml @@ -3,6 +3,12 @@ services: oai-nrf: container_name: "oai-nrf" image: oai-nrf:develop + command: > + bash -c "nohup tshark -i eth0 -w /tmp/nrf.pcap 2>&1 > /dev/null & + /openair-nrf/bin/oai_nrf -c /openair-nrf/etc/nrf.conf -o | tee /tmp/nrf.log 2>&1 + " + cap_add: + - NET_ADMIN environment: - NRF_INTERFACE_NAME_FOR_SBI=eth0 - NRF_INTERFACE_PORT_FOR_SBI=80 @@ -43,6 +49,12 @@ services: oai-amf: container_name: "oai-amf" image: oai-amf:develop + command: > + bash -c "nohup tshark -i eth0 -w /tmp/amf.pcap 2>&1 > /dev/null & + /openair-amf/bin/oai_amf -c /openair-amf/etc/amf.conf -o | tee /tmp/amf.log 2>&1 + " + cap_add: + - NET_ADMIN environment: - TZ=Europe/paris - INSTANCE=0 @@ -108,6 +120,12 @@ services: oai-smf: container_name: "oai-smf" image: oai-smf:develop + command: > + bash -c "nohup tshark -i eth0 -w /tmp/smf.pcap 2>&1 > /dev/null & + /openair-smf/bin/oai_smf -c /openair-smf/etc/smf.conf -o | tee /tmp/smf.log 2>&1 + " + cap_add: + - NET_ADMIN environment: - TZ=Europe/Paris - INSTANCE=0 @@ -151,6 +169,10 @@ services: oai-spgwu: container_name: "oai-spgwu" image: oai-spgwu-tiny:develop + command: > + bash -c "nohup tshark -i eth0 -w /tmp/spgwu.pcap 2>&1 > /dev/null & + /openair-spgwu-tiny/bin/oai_spgwu -c /openair-spgwu-tiny/etc/spgw_u.conf -o | tee /tmp/spgwu.log 2>&1 + " environment: - TZ=Europe/Paris - PID_DIRECTORY=/var/run @@ -214,7 +236,6 @@ networks: public_net: external: name: demo-oai-public-net -# Incase the user wants docker-compose to create a bridge rather than creating the bridge manually then uncomment the below lines public_net: driver: bridge name: demo-oai-public-net diff --git a/docs/CONFIGURE_CONTAINERS.md b/docs/CONFIGURE_CONTAINERS.md index acbccaa..e9ea54b 100644 --- a/docs/CONFIGURE_CONTAINERS.md +++ b/docs/CONFIGURE_CONTAINERS.md @@ -99,43 +99,6 @@ # 3. Networking # -- The [docker-compose.yaml](../docker-compose/docker-compose.yaml) can create the network automatically, currently in the file automatic network creation is disabled. It can be enabled by uncommenting the lines. - - ```bash - networks: - public_net: - driver: bridge - name: demo-oai-public-net - ipam: - config: - - subnet: 192.168.70.128/26 - driver_opts: - com.docker.network.bridge.name: "demo-oai" - ``` - -- In user wants to create manual network then below is the command - -components. To capture initial message exchange between smf<-->nrf<-->upf. - - ```bash - (docker-compose-host)$ docker network create \ - --driver=bridge \ - --subnet=192.168.70.128/26 \ - -o "com.docker.network.bridge.name"="demo-oai" \ - demo-oai-public-net - 455631b3749ccd6f10a366cd1c49d5a66cf976d176884252d5d88a1e54049bc5 - (docker-compose-host)$ ifconfig demo-oai - demo-oai: flags=4099 mtu 1500 - inet 192.168.70.129 netmask 255.255.255.192 broadcast 192.168.70.191 - ether 02:42:9c:0a:23:44 txqueuelen 0 (Ethernet) - RX packets 0 bytes 0 (0.0 B) - RX errors 0 dropped 0 overruns 0 frame 0 - TX packets 0 bytes 0 (0.0 B) - TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 - (docker-compose-host)$ docker network ls - NETWORK ID NAME DRIVER SCOPE - d2d34e05bb2d bridge bridge local - 455631b3749c demo-oai-public-net bridge local - ``` +- The [docker-compose.yaml](../docker-compose/docker-compose.yaml) will create the network automatically. You are ready to check out the tutorial that [how 5g core works](./DEPLOY_SA5G_WITH_DS_TESTER.md). diff --git a/docs/DEPLOY_SA5G_WITH_DS_TESTER.md b/docs/DEPLOY_SA5G_WITH_DS_TESTER.md index f688c93..dbd7d31 100644 --- a/docs/DEPLOY_SA5G_WITH_DS_TESTER.md +++ b/docs/DEPLOY_SA5G_WITH_DS_TESTER.md @@ -62,42 +62,11 @@ To know how to configure the machine with the above requirements vist [pre-requi ## 3. Configuring Host Machines ## -- The `docker-compose-host` machine needs to be configured with `demo-oai-public-net` bridge before deploying core network components. To capture initial message exchange between smf<-->nrf<-->upf. +- The `docker-compose-host` machine will be configured with `demo-oai-public-net` bridge automatically using [docker-compose.yaml](../docker-compose/docker-compose.yaml) at the time of deploying core network components. And also for each component it will start capturing `pcap` messages and stores it on the `/tmp/` location of that container. Use the below command as shown as an example. ```bash - (docker-compose-host)$ docker network create \ - --driver=bridge \ - --subnet=192.168.70.128/26 \ - -o "com.docker.network.bridge.name"="demo-oai" \ - demo-oai-public-net - 455631b3749ccd6f10a366cd1c49d5a66cf976d176884252d5d88a1e54049bc5 - (docker-compose-host)$ ifconfig demo-oai - demo-oai: flags=4099 mtu 1500 - inet 192.168.70.129 netmask 255.255.255.192 broadcast 192.168.70.191 - ether 02:42:9c:0a:23:44 txqueuelen 0 (Ethernet) - RX packets 0 bytes 0 (0.0 B) - RX errors 0 dropped 0 overruns 0 frame 0 - TX packets 0 bytes 0 (0.0 B) - TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 - (docker-compose-host)$ docker network ls - NETWORK ID NAME DRIVER SCOPE - d2d34e05bb2d bridge bridge local - 455631b3749c demo-oai-public-net bridge local + (docker-compose-host)$ docker cp container_name:/tmp/amf.pcap amf.pcap ``` -- Optional, Though the bridge can be automatically created using docker-compose file if there is no need to capture initial packets. Uncomment the last lines of the [docker-compose.yaml](../docker-compose/docker-compose.yaml) or docker-compose-no-nrf.yaml. Else replace with below section - - ``` - networks: - public_net: - driver: bridge - name: demo-oai-public-net - ipam: - config: - - subnet: 192.168.70.128/26 - driver_opts: - com.docker.network.bridge.name: "demo-oai" - ``` - - Optional, if the `docker-compose-host` machine is not configured with packet forwarding then it can be done using below command, -- GitLab