mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-15 05:30:29 +00:00
Compare commits
90 Commits
bugfix-ldp
...
o1-integra
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d73b07475f | ||
|
|
d67c03a264 | ||
|
|
c15e00f3e9 | ||
|
|
ccd46058c6 | ||
|
|
7598c0cac7 | ||
|
|
c66eec2b7d | ||
|
|
a61e569cb2 | ||
|
|
006aaaaa8d | ||
|
|
9d8dad92b5 | ||
|
|
bfab79924a | ||
|
|
3d26fc5146 | ||
|
|
7045fd089c | ||
|
|
5d58645a85 | ||
|
|
d501025037 | ||
|
|
5b2b0432c9 | ||
|
|
1f21757d62 | ||
|
|
206f8ae187 | ||
|
|
60bf3a9869 | ||
|
|
d0bc613d64 | ||
|
|
b74ba0fb92 | ||
|
|
565b8482f9 | ||
|
|
fc7bcceca9 | ||
|
|
08e57ca313 | ||
|
|
3674a6f0f2 | ||
|
|
924d88bbf9 | ||
|
|
90a836a022 | ||
|
|
f9f6283cc3 | ||
|
|
214aa50595 | ||
|
|
7d3100dbe7 | ||
|
|
18b9135c4f | ||
|
|
75e542c6ad | ||
|
|
da099ca77a | ||
|
|
f36d7e8e96 | ||
|
|
1e812a4b7c | ||
|
|
2c3e4ef47f | ||
|
|
47a4da8d5f | ||
|
|
3598180557 | ||
|
|
a040fbddf2 | ||
|
|
6620471822 | ||
|
|
da70a37551 | ||
|
|
ce1246e0dd | ||
|
|
3b4371e01c | ||
|
|
6886f0d3dd | ||
|
|
451937d88b | ||
|
|
b780c9db80 | ||
|
|
096a32bf16 | ||
|
|
cdf7fb6f70 | ||
|
|
3b9107228a | ||
|
|
57dbc79668 | ||
|
|
074cf91bec | ||
|
|
941acb2e8d | ||
|
|
7361c1689e | ||
|
|
de4a9e1d5a | ||
|
|
ce03b84898 | ||
|
|
affa5e3086 | ||
|
|
89bddc76f0 | ||
|
|
21ef822c45 | ||
|
|
9a789dbb8a | ||
|
|
24237b3e35 | ||
|
|
1434175a84 | ||
|
|
b7762141e8 | ||
|
|
551aee172a | ||
|
|
719e36159d | ||
|
|
01030bbc4e | ||
|
|
f277a27f57 | ||
|
|
5300c57f3d | ||
|
|
e55e880b71 | ||
|
|
1e6db77be7 | ||
|
|
675ebb1f22 | ||
|
|
ad6c250595 | ||
|
|
00c36d7b40 | ||
|
|
a7db9280b8 | ||
|
|
c6bfb97988 | ||
|
|
f7a34d4274 | ||
|
|
4c6a1c722b | ||
|
|
01ddccb101 | ||
|
|
b95b95e7a7 | ||
|
|
44dabd7377 | ||
|
|
93770edc8a | ||
|
|
4a518335bb | ||
|
|
9de7f5838b | ||
|
|
10e9474e67 | ||
|
|
387ff92ab3 | ||
|
|
69b6d7ed5b | ||
|
|
a74ced54a2 | ||
|
|
cc04996bd5 | ||
|
|
c4963ed16d | ||
|
|
3e3dd82433 | ||
|
|
c54cf49f27 | ||
|
|
ef65ad6cd5 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -22,3 +22,8 @@ tags
|
||||
nfapi_nr_interface_scf
|
||||
*.log
|
||||
*.out
|
||||
|
||||
**/*_3gpp*.yang
|
||||
**/specification/available-yangs
|
||||
**/integration/dcae/externalRepo
|
||||
/dev
|
||||
|
||||
@@ -525,7 +525,6 @@ target_link_libraries(f1ap PRIVATE ngap nr_rrc)
|
||||
##############
|
||||
# target asn1_lpp in openair3/LPP/MESSAGES/CMakeLists.txt used below
|
||||
|
||||
|
||||
# Hardware dependant options
|
||||
###################################
|
||||
add_list1_option(NB_ANTENNAS_RX "4" "Number of antennas in reception" "1" "2" "4")
|
||||
@@ -2430,6 +2429,13 @@ add_executable(nr-softmodem
|
||||
${OPENAIR_DIR}/common/utils/lte/ue_power.c
|
||||
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/common/utils/netconf/netconf_session.c
|
||||
${OPENAIR_DIR}/common/utils/netconf/netconf.c
|
||||
${OPENAIR_DIR}/common/utils/netconf/netconf_demos.c
|
||||
${OPENAIR_DIR}/common/utils/netconf/o1config.c
|
||||
${OPENAIR_DIR}/common/utils/netconf/utils.c
|
||||
${OPENAIR_DIR}/common/utils/netconf/ves_demo_alarm.c
|
||||
${OPENAIR_DIR}/common/utils/netconf/ves.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${XFORMSINTERFACE_SOURCE}
|
||||
${T_SOURCE}
|
||||
@@ -2449,6 +2455,7 @@ target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYPT
|
||||
target_link_libraries(nr-softmodem PRIVATE ${LIB_LMS_LIBRARIES})
|
||||
target_link_libraries(nr-softmodem PRIVATE ${T_LIB})
|
||||
target_link_libraries(nr-softmodem PRIVATE asn1_nr_rrc asn1_lte_rrc)
|
||||
target_link_libraries(nr-softmodem PRIVATE yang sysrepo curl)
|
||||
|
||||
add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc)
|
||||
|
||||
@@ -2843,6 +2850,7 @@ if(OAI_NW_DRIVER_USE_NETLINK)
|
||||
endif()
|
||||
make_driver(ue_ip ${OPENAIR2_DIR}/NETWORK_DRIVER/UE_IP ${ue_ip_src})
|
||||
|
||||
#include (common/utils/netconf/netconf_CMakeLists.txt)
|
||||
include (common/utils/telnetsrv/telnetsrv_CMakeLists.txt)
|
||||
include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt)
|
||||
include (${OPENAIR_DIR}/common/utils/websrv/websrv_CMakeLists.txt)
|
||||
|
||||
@@ -12,6 +12,8 @@ We want to make contributing to this project as easy and transparent as possible
|
||||
* This decision was made for the license reasons.
|
||||
* The Continuous Integration will reject your merge request.
|
||||
- All merge requests SHALL have `develop` branch as target branch.
|
||||
- All merge requests SHALL have source branch names that SHALL not contain the `/` character.
|
||||
* We are using a `docker` registry scheme and the image names are based on the source branch name.
|
||||
|
||||
## Coding Styles ##
|
||||
|
||||
|
||||
80
build-gnb-docker.sh
Executable file
80
build-gnb-docker.sh
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/bin/bash
|
||||
OSBASE="ubuntu22"
|
||||
TIMESTAMP=$(date -u +'%Y%m%dT%H%M%SZ')
|
||||
TIMESTAMP_TAG="$OSBASE-$TIMESTAMP"
|
||||
BUILD_RAN_BASE="false"
|
||||
BUILD_RAN_BUILD="false"
|
||||
BUILD_RAN_DEV="false"
|
||||
BUILD_RAN_GNB="false"
|
||||
|
||||
until [ -z "$1" ]
|
||||
do
|
||||
case "$1" in
|
||||
--all)
|
||||
BUILD_RAN_BASE="true"
|
||||
BUILD_RAN_BUILD="true"
|
||||
BUILD_RAN_DEV="true"
|
||||
BUILD_RAN_GNB="true"
|
||||
shift
|
||||
;;
|
||||
|
||||
--base)
|
||||
BUILD_RAN_BASE="true"
|
||||
shift
|
||||
;;
|
||||
|
||||
--build)
|
||||
BUILD_RAN_BUILD="true"
|
||||
shift
|
||||
;;
|
||||
|
||||
--dev)
|
||||
BUILD_RAN_DEV="true"
|
||||
shift
|
||||
;;
|
||||
|
||||
--gnb)
|
||||
BUILD_RAN_GNB="true"
|
||||
shift
|
||||
;;
|
||||
|
||||
--no-cache)
|
||||
NO_CACHE="--no-cache"
|
||||
shift
|
||||
;;
|
||||
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if ! $BUILD_RAN_BUILD && ! $BUILD_RAN_GNB && ! $BUILD_RAN_DEV && ! $BUILD_RAN_GNB; then
|
||||
BUILD_RAN_BUILD="true"
|
||||
BUILD_RAN_GNB="true"
|
||||
fi
|
||||
|
||||
if $BUILD_RAN_BASE; then
|
||||
docker build $NO_CACHE --target ran-base --tag ran-base:$OSBASE-latest --file docker/Dockerfile.base.$OSBASE .
|
||||
if [ ! $? -eq 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if $BUILD_RAN_BUILD; then
|
||||
docker build $NO_CACHE --target ran-build --build-arg BASETAG=$OSBASE-latest --tag ran-build:$OSBASE-latest --file docker/Dockerfile.build.$OSBASE .
|
||||
if [ ! $? -eq 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if $BUILD_RAN_DEV; then
|
||||
docker build $NO_CACHE --target ran-dev --build-arg BASETAG=$OSBASE-latest --tag ran-dev:$OSBASE-latest --file docker/Dockerfile.dev.$OSBASE .
|
||||
if [ ! $? -eq 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if $BUILD_RAN_GNB; then
|
||||
docker build $NO_CACHE --target oai-gnb --build-arg BASETAG=$OSBASE-latest --tag oai-gnb:$OSBASE-latest --tag oai-gnb:$TIMESTAMP_TAG --file docker/Dockerfile.gNB.ubuntu22 .
|
||||
if [ ! $? -eq 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
@@ -1,391 +0,0 @@
|
||||
#!/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
|
||||
*/
|
||||
|
||||
// Location of the executor node
|
||||
def nodeExecutor = params.nodeExecutor
|
||||
|
||||
// VM Lockable resources
|
||||
def vmResource = params.vmLockableResource
|
||||
|
||||
// Tags to shorten pipeline duration
|
||||
def doMandatoryTests = false
|
||||
def doFullTestsuite = false
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
label nodeExecutor
|
||||
}
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
timestamps()
|
||||
gitLabConnection('OAI GitLab')
|
||||
ansiColor('xterm')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage ("Verify Parameters") {
|
||||
steps {
|
||||
script {
|
||||
JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"'
|
||||
JOB_TIMESTAMP = JOB_TIMESTAMP.trim()
|
||||
|
||||
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
|
||||
def allParametersPresent = true
|
||||
if (env.TESTPLATFORM_OWNER) {
|
||||
echo "Platform is ${env.TESTPLATFORM_OWNER}"
|
||||
}
|
||||
|
||||
echo '\u2705 \u001B[32mVerify Labels\u001B[0m'
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
LABEL_CHECK = sh returnStdout: true, script: 'ci-scripts/checkGitLabMergeRequestLabels.sh --mr-id ' + env.gitlabMergeRequestIid
|
||||
LABEL_CHECK = LABEL_CHECK.trim()
|
||||
if (LABEL_CHECK == 'NONE') {
|
||||
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Your merge request has none of the mandatory labels:\n\n"
|
||||
message += " - BUILD-ONLY\n"
|
||||
message += " - 4G-LTE\n"
|
||||
message += " - 5G-NR\n"
|
||||
message += " - CI\n\n"
|
||||
message += "Not performing CI due to lack of labels"
|
||||
addGitLabMRComment comment: message
|
||||
error('Not performing CI due to lack of labels')
|
||||
} else if (LABEL_CHECK == 'FULL' || LABEL_CHECK == 'SHORTEN-4G') {
|
||||
doMandatoryTests = true
|
||||
doFullTestsuite = true
|
||||
} else if (LABEL_CHECK == 'SHORTEN-5G') {
|
||||
doMandatoryTests = true
|
||||
} else {
|
||||
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): We will perform only build stages on your Merge Request"
|
||||
addGitLabMRComment comment: message
|
||||
}
|
||||
} else {
|
||||
doMandatoryTests = true
|
||||
doFullTestsuite = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Verify Guidelines") {
|
||||
steps {
|
||||
echo "Git URL is ${GIT_URL}"
|
||||
echo "GitLab Act is ${env.gitlabActionType}"
|
||||
script {
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
// since a bit, in push events, gitlabUserEmail is not populated
|
||||
gitCommitAuthorEmailAddr = env.gitlabUserEmail
|
||||
echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}"
|
||||
// GitLab-Jenkins plugin integration is lacking to perform the merge by itself
|
||||
// Doing it manually --> it may have merge conflicts
|
||||
sh "./ci-scripts/doGitLabMerge.sh --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
|
||||
sh "zip -r -qq localZip.zip ."
|
||||
|
||||
// here was an astyle formatting check, with corresponding messages. The same could be done with clang-format
|
||||
} else {
|
||||
echo "Git Branch is ${GIT_BRANCH}"
|
||||
echo "Git Commit is ${GIT_COMMIT}"
|
||||
// since a bit, in push events, gitlabUserEmail is not populated
|
||||
gitCommitAuthorEmailAddr = sh returnStdout: true, script: 'git log -n1 --pretty=format:%ae ${GIT_COMMIT}'
|
||||
gitCommitAuthorEmailAddr = gitCommitAuthorEmailAddr.trim()
|
||||
echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}"
|
||||
sh "git log -n1 --pretty=format:\"%s\" > .git/CI_COMMIT_MSG"
|
||||
|
||||
sh "zip -r -qq localZip.zip ."
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
failure {
|
||||
script {
|
||||
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Merge Conflicts -- Cannot perform CI"
|
||||
addGitLabMRComment comment: message
|
||||
currentBuild.result = 'FAILURE'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ("Start VM -- gnb-usrp") {
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
timeout (time: 5, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ("Start VM -- nr-ue-usrp") {
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
timeout (time: 5, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ("Start VM -- enb-ethernet") {
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
timeout (time: 7, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ("Start VM -- ue-ethernet") {
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
timeout (time: 7, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ("Variant Builds") {
|
||||
parallel {
|
||||
stage ("Build 5G gNB-USRP") {
|
||||
steps {
|
||||
gitlabCommitStatus(name: "Build gNB-USRP") {
|
||||
timeout (time: 45, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Build 5G NR-UE-USRP") {
|
||||
steps {
|
||||
gitlabCommitStatus(name: "Build nr-UE-USRP") {
|
||||
timeout (time: 45, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Build eNB-ethernet") {
|
||||
steps {
|
||||
gitlabCommitStatus(name: "Build eNB-ethernet") {
|
||||
timeout (time: 45, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Build UE-ethernet") {
|
||||
steps {
|
||||
// This is typically the last one to finish.
|
||||
lock (vmResource) {
|
||||
gitlabCommitStatus(name: "Build UE-ethernet") {
|
||||
timeout (time: 45, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
failure {
|
||||
script {
|
||||
currentBuild.result = 'FAILURE'
|
||||
}
|
||||
}
|
||||
always {
|
||||
script {
|
||||
dir ('archives') {
|
||||
if (fileExists('red_hat')) {
|
||||
sh "zip -r -qq vm_build_logs.zip enb_eth ue_eth gnb_usrp nr_ue_usrp red_hat"
|
||||
} else {
|
||||
sh "zip -r -qq vm_build_logs.zip enb_eth ue_eth gnb_usrp nr_ue_usrp"
|
||||
}
|
||||
}
|
||||
if(fileExists('archives/vm_build_logs.zip')) {
|
||||
archiveArtifacts artifacts: 'archives/vm_build_logs.zip'
|
||||
}
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
sh "./ci-scripts/oai-ci-vm-tool report-build --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
|
||||
// If the merge request has introduced compilation warnings, notifications in GitLab
|
||||
sh "./ci-scripts/checkAddedWarnings.sh --src-branch ${env.gitlabSourceBranch} --target-branch ${env.gitlabTargetBranch}"
|
||||
def res=readFile('./oai_warning_files.txt').trim();
|
||||
if ("0".equals(res)) {
|
||||
echo "No issues w/ warnings/errors in this merge request"
|
||||
} else {
|
||||
def fileList=readFile('./oai_warning_files_list.txt').trim();
|
||||
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Some modified files in Merge Request MAY have INTRODUCED WARNINGS (" + fileList + ")"
|
||||
addGitLabMRComment comment: message
|
||||
}
|
||||
} else {
|
||||
sh "./ci-scripts/oai-ci-vm-tool report-build --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger push --branch ${GIT_BRANCH} --commit ${GIT_COMMIT}"
|
||||
}
|
||||
if(fileExists('build_results.html')) {
|
||||
sh "sed -i -e 's#Build-ID: ${BUILD_ID}#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' build_results.html"
|
||||
archiveArtifacts artifacts: 'build_results.html'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ("Variant Tests") {
|
||||
parallel {
|
||||
stage ("VM-based tests") {
|
||||
stages {
|
||||
stage ("Test L1 simulator") {
|
||||
when {
|
||||
expression {doMandatoryTests}
|
||||
}
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
script {
|
||||
timeout (time: 30, unit: 'MINUTES') {
|
||||
try {
|
||||
gitlabCommitStatus(name: "Test L1-sim") {
|
||||
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l1-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Test RF simulator") {
|
||||
when {
|
||||
expression {doMandatoryTests}
|
||||
}
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
script {
|
||||
timeout (time: 40, unit: 'MINUTES') {
|
||||
try {
|
||||
gitlabCommitStatus(name: "Test RF-sim") {
|
||||
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant rf-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Test 5G RF simulator") {
|
||||
when {
|
||||
expression {doMandatoryTests}
|
||||
}
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
script {
|
||||
timeout (time: 40, unit: 'MINUTES') {
|
||||
try {
|
||||
gitlabCommitStatus(name: "Test 5G RF-sim") {
|
||||
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant rf5g-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Destroy all Virtual Machines") {
|
||||
when {
|
||||
expression {doMandatoryTests}
|
||||
}
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
if (doMandatoryTests) {
|
||||
dir ('archives') {
|
||||
sh "if [ -d rf_sim/test ] || [ -d rf5g_sim/test ] || [ -d l2_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi"
|
||||
}
|
||||
if(fileExists('archives/vm_tests_logs.zip')) {
|
||||
archiveArtifacts artifacts: 'archives/vm_tests_logs.zip'
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
sh "./ci-scripts/oai-ci-vm-tool report-test --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
|
||||
} else {
|
||||
sh "./ci-scripts/oai-ci-vm-tool report-test --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger push --branch ${GIT_BRANCH} --commit ${GIT_COMMIT}"
|
||||
}
|
||||
if(fileExists('test_simulator_results.html')) {
|
||||
sh "sed -i -e 's#Build-ID: ${BUILD_ID}#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_simulator_results.html"
|
||||
archiveArtifacts artifacts: 'test_simulator_results.html'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
// Stage destroy may not be run if error in previous stage
|
||||
sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
|
||||
emailext attachmentsPattern: '*results*.html',
|
||||
body: '''Hi,
|
||||
|
||||
Here are attached HTML report files for $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!
|
||||
|
||||
Regards,
|
||||
OAI CI Team''',
|
||||
replyTo: 'no-reply@openairinterface.org',
|
||||
subject: '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!',
|
||||
to: gitCommitAuthorEmailAddr
|
||||
|
||||
if (fileExists('.git/CI_COMMIT_MSG')) {
|
||||
sh "rm -f .git/CI_COMMIT_MSG"
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
script {
|
||||
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ")"
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
echo "This is a MERGE event"
|
||||
addGitLabMRComment comment: message
|
||||
}
|
||||
}
|
||||
}
|
||||
failure {
|
||||
script {
|
||||
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ")"
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
echo "This is a MERGE event"
|
||||
addGitLabMRComment comment: message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/bin/bash
|
||||
while true
|
||||
do
|
||||
echo "gNB will be started automatically..."
|
||||
sleep 1
|
||||
sudo .././cmake_targets/ran_build/build/nr-softmodem -E -O ../targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
|
||||
done
|
||||
@@ -1,236 +0,0 @@
|
||||
#!/bin/bash
|
||||
#/*
|
||||
# * 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
|
||||
# */
|
||||
|
||||
function build_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo " Requirements:"
|
||||
echo " -- uvtool uvtool-libvirt apt-cacher"
|
||||
echo " -- $VM_OSREL image already synced"
|
||||
echo " Default:"
|
||||
echo " -- eNB with USRP"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo " oai-ci-vm-tool build [OPTIONS]"
|
||||
echo ""
|
||||
command_options_usage
|
||||
|
||||
}
|
||||
|
||||
function build_on_vm {
|
||||
if [ ! -f $JENKINS_WKSP/localZip.zip ]
|
||||
then
|
||||
echo "Missing localZip.zip file!"
|
||||
STATUS=1
|
||||
return
|
||||
fi
|
||||
if [[ ! -f /etc/apt/apt.conf.d/01proxy ]] && [[ "$OPTIONAL_APTCACHER" != "true" ]]
|
||||
then
|
||||
echo "Missing /etc/apt/apt.conf.d/01proxy file!"
|
||||
echo "Is apt-cacher installed and configured?"
|
||||
STATUS=1
|
||||
return
|
||||
fi
|
||||
|
||||
echo "############################################################"
|
||||
echo "OAI CI VM script"
|
||||
echo "############################################################"
|
||||
|
||||
echo "VM_NAME = $VM_NAME"
|
||||
echo "VM_CMD_FILE = $VM_CMDS"
|
||||
echo "JENKINS_WKSP = $JENKINS_WKSP"
|
||||
echo "ARCHIVES_LOC = $ARCHIVES_LOC"
|
||||
echo "BUILD_OPTIONS = $BUILD_OPTIONS"
|
||||
|
||||
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]] || [[ "$VM_NAME" == *"-basic-sim"* ]] || [[ "$VM_NAME" == *"-flexran-rtc"* ]] || [[ "$VM_NAME" == *"-rf-sim"* ]] || [[ "$VM_NAME" == *"-ethernet"* ]] || [[ "$VM_NAME" == *"rf5g-sim"* ]] || [[ "$VM_NAME" == *"gnb-usrp"* ]] || [[ "$VM_NAME" == *"nr-ue-usrp"* ]]
|
||||
then
|
||||
echo "This VM type is no longer supported in the pipeline framework"
|
||||
return
|
||||
fi
|
||||
|
||||
IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME`
|
||||
|
||||
if [ $IS_VM_ALIVE -eq 0 ]
|
||||
then
|
||||
echo "VM_MEMORY = $VM_MEMORY MBytes"
|
||||
echo "VM_CPU = $VM_CPU"
|
||||
echo "VM_DISK = $VM_DISK GBytes"
|
||||
echo "############################################################"
|
||||
echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base"
|
||||
echo "############################################################"
|
||||
acquire_vm_create_lock
|
||||
uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml
|
||||
echo "Waiting for VM to be started"
|
||||
uvt-kvm wait $VM_NAME --insecure
|
||||
|
||||
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
|
||||
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
|
||||
release_vm_create_lock
|
||||
else
|
||||
echo "Waiting for VM to be started"
|
||||
uvt-kvm wait $VM_NAME --insecure
|
||||
|
||||
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
|
||||
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
|
||||
fi
|
||||
|
||||
echo "############################################################"
|
||||
echo "Copying GIT repo into VM ($VM_NAME)"
|
||||
echo "############################################################"
|
||||
if [[ "$VM_NAME" == *"-flexran-rtc"* ]]
|
||||
then
|
||||
scp -o StrictHostKeyChecking=no $JENKINS_WKSP/flexran/flexran.zip ubuntu@$VM_IP_ADDR:/home/ubuntu/localZip.zip
|
||||
else
|
||||
scp -o StrictHostKeyChecking=no $JENKINS_WKSP/localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu
|
||||
fi
|
||||
[ -f /etc/apt/apt.conf.d/01proxy ] && scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu
|
||||
|
||||
echo "############################################################"
|
||||
echo "Running install and build script on VM ($VM_NAME)"
|
||||
echo "############################################################"
|
||||
echo "[ -f 01proxy ] && sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS
|
||||
echo "touch /home/ubuntu/.hushlogin" >> $VM_CMDS
|
||||
echo "git config --global https.postBuffer 123289600" >> $VM_CMDS
|
||||
if [[ "$VM_NAME" == *"-cppcheck"* ]]
|
||||
then
|
||||
if [ $DAEMON -eq 0 ]
|
||||
then
|
||||
echo "echo \"sudo apt-get --yes --quiet install zip cppcheck \"" >> $VM_CMDS
|
||||
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
|
||||
echo "sudo apt-get --yes install zip cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
else
|
||||
echo "echo \"sudo apt-get --yes --quiet install zip daemon cppcheck \"" >> $VM_CMDS
|
||||
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
|
||||
echo "sudo apt-get --yes install zip daemon cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
fi
|
||||
fi
|
||||
if [[ "$VM_NAME" == *"-flexran-rtc"* ]]
|
||||
then
|
||||
if [ $DAEMON -eq 0 ]
|
||||
then
|
||||
echo "echo \"sudo apt-get --yes --quiet install zip curl jq \"" >> $VM_CMDS
|
||||
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
|
||||
echo "sudo apt-get --yes install zip curl jq >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
else
|
||||
echo "echo \"sudo apt-get --yes --quiet install zip daemon curl jq \"" >> $VM_CMDS
|
||||
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
|
||||
echo "sudo apt-get --yes install zip daemon curl jq >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
fi
|
||||
fi
|
||||
if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]]
|
||||
then
|
||||
if [ $DAEMON -eq 0 ]
|
||||
then
|
||||
echo "echo \"sudo apt-get --yes --quiet install zip subversion libboost-dev \"" >> $VM_CMDS
|
||||
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
|
||||
if [[ "$VM_NAME" == *"-phy-sim"* ]]
|
||||
then
|
||||
echo "sudo apt-get --yes install zip subversion libboost-dev make gcc >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
else
|
||||
echo "sudo apt-get --yes install zip subversion libboost-dev >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
fi
|
||||
else
|
||||
echo "echo \"sudo apt-get --yes --quiet install zip daemon subversion libboost-dev \"" >> $VM_CMDS
|
||||
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
|
||||
if [[ "$VM_NAME" == *"-phy-sim"* ]]
|
||||
then
|
||||
echo "sudo apt-get --yes install zip daemon subversion libboost-dev make gcc >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
else
|
||||
echo "sudo apt-get --yes install zip daemon subversion libboost-dev >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo "mkdir tmp" >> $VM_CMDS
|
||||
echo "cd tmp" >> $VM_CMDS
|
||||
echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $VM_CMDS
|
||||
echo "unzip -qq -DD ../localZip.zip" >> $VM_CMDS
|
||||
# Trying to make some room on filesystem before building
|
||||
echo "rm ../localZip.zip" >> $VM_CMDS
|
||||
echo "export CI_ENV=True" >> $VM_CMDS
|
||||
if [[ "$VM_NAME" == *"-cppcheck"* ]]
|
||||
then
|
||||
echo "mkdir cmake_targets/log" >> $VM_CMDS
|
||||
echo "chmod 777 cmake_targets/log" >> $VM_CMDS
|
||||
echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS
|
||||
echo "echo \"cppcheck $BUILD_OPTIONS . \"" >> $VM_CMDS
|
||||
if [ $DAEMON -eq 0 ]
|
||||
then
|
||||
echo "cppcheck $BUILD_OPTIONS . 2> cmake_targets/log/cppcheck.xml 1> cmake_targets/log/cppcheck_build.txt" >> $VM_CMDS
|
||||
else
|
||||
echo "echo \"cppcheck $BUILD_OPTIONS .\" > ./my-vm-build.sh" >> $VM_CMDS
|
||||
echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS
|
||||
echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp -O /home/ubuntu/tmp/cmake_targets/log/cppcheck_build.txt -E /home/ubuntu/tmp/cmake_targets/log/cppcheck.xml ./my-vm-build.sh" >> $VM_CMDS
|
||||
fi
|
||||
fi
|
||||
if [[ "$VM_NAME" == *"-flexran-rtc"* ]]
|
||||
then
|
||||
echo "mkdir -p cmake_targets/log" >> $VM_CMDS
|
||||
echo "chmod 777 cmake_targets/log" >> $VM_CMDS
|
||||
echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS
|
||||
# Patching the pistache build for Xenial (cmake too old for new commits)
|
||||
echo "sed -i -e 's@cd pistache@cd pistache \&\& git checkout -f 9a65f40975fafca5bb5370ba6d0d00f42cbc4356@' ./tools/install_dependencies" >> $VM_CMDS
|
||||
echo "echo \"./tools/install_dependencies \"" >> $VM_CMDS
|
||||
echo "./tools/install_dependencies > cmake_targets/log/install-build.txt 2>&1" >> $VM_CMDS
|
||||
echo "echo \"mkdir build\"" >> $VM_CMDS
|
||||
echo "mkdir build" >> $VM_CMDS
|
||||
echo "echo \"cd build\"" >> $VM_CMDS
|
||||
echo "cd build" >> $VM_CMDS
|
||||
echo "echo \"$BUILD_OPTIONS \"" >> $VM_CMDS
|
||||
echo "$BUILD_OPTIONS > ../cmake_targets/log/rt_controller.txt 2>&1" >> $VM_CMDS
|
||||
fi
|
||||
if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]]
|
||||
then
|
||||
echo "echo \"source oaienv\"" >> $VM_CMDS
|
||||
echo "source oaienv" >> $VM_CMDS
|
||||
if [[ "$VM_NAME" == *"-phy-sim"* ]]
|
||||
then
|
||||
echo "cd common/utils/T" >> $VM_CMDS
|
||||
echo "make" >> $VM_CMDS
|
||||
echo "cd ../../.." >> $VM_CMDS
|
||||
fi
|
||||
echo "cd cmake_targets/" >> $VM_CMDS
|
||||
echo "mkdir log" >> $VM_CMDS
|
||||
echo "chmod 777 log" >> $VM_CMDS
|
||||
echo "cp /home/ubuntu/zip-install.txt log" >> $VM_CMDS
|
||||
if [ $DAEMON -eq 0 ]
|
||||
then
|
||||
echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS
|
||||
echo "./build_oai -I $BUILD_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS
|
||||
else
|
||||
if [[ "$VM_NAME" == *"-enb-ethernet"* ]]
|
||||
then
|
||||
echo "echo \"sleep 170 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
|
||||
elif [[ "$VM_NAME" == *"-ue-ethernet"* ]]
|
||||
then
|
||||
echo "echo \"sleep 60 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
|
||||
else
|
||||
echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
|
||||
fi
|
||||
echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS
|
||||
echo "echo \"sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh\"" >> $VM_CMDS
|
||||
echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh" >> $VM_CMDS
|
||||
fi
|
||||
fi
|
||||
ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS
|
||||
rm -f $VM_CMDS
|
||||
}
|
||||
@@ -19,29 +19,27 @@
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
# Python for CI of OAI-eNB + COTS-UE
|
||||
#
|
||||
# Required Python Version
|
||||
# Python 3.x
|
||||
#
|
||||
# Required Python Package
|
||||
# pexpect
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# Import
|
||||
#-----------------------------------------------------------
|
||||
import logging
|
||||
import sshconnection as SSH
|
||||
import cls_oai_html
|
||||
#import os
|
||||
import re
|
||||
import time
|
||||
#import subprocess
|
||||
import sys
|
||||
|
||||
import cls_oai_html
|
||||
import constants as CONST
|
||||
import helpreadme as HELP
|
||||
import cls_containerize
|
||||
import cls_cmd
|
||||
|
||||
IMAGE_REGISTRY_SERVICE_NAME = "image-registry.openshift-image-registry.svc"
|
||||
NAMESPACE = "oaicicd-ran"
|
||||
|
||||
class Cluster:
|
||||
def __init__(self):
|
||||
@@ -58,86 +56,73 @@ class Cluster:
|
||||
self.ranCommitID = ""
|
||||
self.ranAllowMerge = False
|
||||
self.ranTargetBranch = ""
|
||||
self.cmd = None
|
||||
|
||||
def _recreate_entitlements(self, sshSession):
|
||||
|
||||
def _recreate_entitlements(self):
|
||||
# recreating entitlements, don't care if deletion fails
|
||||
sshSession.command('oc delete secret etc-pki-entitlement', '\$', 5)
|
||||
if re.search(r"not found", sshSession.getBefore()):
|
||||
logging.warning("no secrets etc-pki-entitlement found, recreating")
|
||||
sshSession.command('ls /etc/pki/entitlement/???????????????????.pem | tail -1', '\$', 5, silent=True)
|
||||
regres1 = re.search(r"/etc/pki/entitlement/[0-9]+.pem", sshSession.getBefore())
|
||||
sshSession.command('ls /etc/pki/entitlement/???????????????????-key.pem | tail -1', '\$', 5, silent=True)
|
||||
regres2 = re.search(r"/etc/pki/entitlement/[0-9]+-key.pem", sshSession.getBefore())
|
||||
self.cmd.run('oc delete secret etc-pki-entitlement')
|
||||
ret = self.cmd.run('ls /etc/pki/entitlement/???????????????????.pem | tail -1', silent=True)
|
||||
regres1 = re.search(r"/etc/pki/entitlement/[0-9]+.pem", ret.stdout)
|
||||
ret = self.cmd.run('ls /etc/pki/entitlement/???????????????????-key.pem | tail -1', silent=True)
|
||||
regres2 = re.search(r"/etc/pki/entitlement/[0-9]+-key.pem", ret.stdout)
|
||||
if regres1 is None or regres2 is None:
|
||||
logging.error("could not find entitlements")
|
||||
return False
|
||||
file1 = regres1.group(0)
|
||||
file2 = regres2.group(0)
|
||||
sshSession.command(f'oc create secret generic etc-pki-entitlement --from-file {file1} --from-file {file2}', '\$', 5)
|
||||
regres = re.search(r"secret/etc-pki-entitlement created", sshSession.getBefore())
|
||||
if regres is None:
|
||||
ret = self.cmd.run(f'oc create secret generic etc-pki-entitlement --from-file {file1} --from-file {file2}')
|
||||
regres = re.search(r"secret/etc-pki-entitlement created", ret.stdout)
|
||||
if ret.returncode != 0 or regres is None:
|
||||
logging.error("could not create secret/etc-pki-entitlement")
|
||||
return False
|
||||
return True
|
||||
|
||||
def _recreate_bc(self, sshSession, name, newTag, filename):
|
||||
self._retag_image_statement(sshSession, name, name, newTag, filename)
|
||||
sshSession.command(f'oc delete -f {filename}', '\$', 5)
|
||||
sshSession.command(f'oc create -f {filename}', '\$', 5)
|
||||
before = sshSession.getBefore()
|
||||
if re.search('buildconfig.build.openshift.io/[a-zA-Z\-0-9]+ created', before) is not None:
|
||||
def _recreate_bc(self, name, newTag, filename):
|
||||
self._retag_image_statement(name, name, newTag, filename)
|
||||
self.cmd.run(f'oc delete -f {filename}')
|
||||
ret = self.cmd.run(f'oc create -f {filename}')
|
||||
if re.search('buildconfig.build.openshift.io/[a-zA-Z\-0-9]+ created', ret.stdout) is not None:
|
||||
return True
|
||||
logging.error('error while creating buildconfig: ' + sshSession.getBefore())
|
||||
logging.error('error while creating buildconfig: ' + ret.stdout)
|
||||
return False
|
||||
|
||||
def _recreate_is_tag(self, sshSession, name, newTag, filename):
|
||||
sshSession.command(f'oc describe is {name}', '\$', 5)
|
||||
if sshSession.getBefore().count('NotFound') > 0:
|
||||
sshSession.command(f'oc create -f {filename}', '\$', 5)
|
||||
before = sshSession.getBefore()
|
||||
if re.search(f'imagestream.image.openshift.io/{name} created', before) is None:
|
||||
logging.error('error while creating imagestream: ' + sshSession.getBefore())
|
||||
def _recreate_is_tag(self, name, newTag, filename):
|
||||
ret = self.cmd.run(f'oc describe is {name}')
|
||||
if ret.returncode != 0:
|
||||
ret = self.cmd.run(f'oc create -f {filename}')
|
||||
if ret.returncode != 0:
|
||||
logging.error(f'error while creating imagestream: {ret.stdout}')
|
||||
return False
|
||||
else:
|
||||
logging.debug(f'-> imagestream {name} found')
|
||||
image = f'{name}:{newTag}'
|
||||
sshSession.command(f'oc delete istag {image}', '\$', 5) # we don't care if this fails, e.g., if it is missing
|
||||
sshSession.command(f'oc create istag {image}', '\$', 5)
|
||||
before = sshSession.getBefore()
|
||||
if re.search(f'imagestreamtag.image.openshift.io/{image} created', before) is not None:
|
||||
self.cmd.run(f'oc delete istag {image}', reportNonZero=False) # we don't care if this fails, e.g., if it is missing
|
||||
ret = self.cmd.run(f'oc create istag {image}')
|
||||
if ret.returncode == 0:
|
||||
return True
|
||||
logging.error('error while creating imagestreamtag: ' + sshSession.getBefore())
|
||||
logging.error(f'error while creating imagestreamtag: {ret.stdout}')
|
||||
return False
|
||||
|
||||
def _start_build(self, sshSession, name):
|
||||
def _start_build(self, name):
|
||||
# will return "immediately" but build runs in background
|
||||
# if multiple builds are started at the same time, this can take some time, however
|
||||
ret = sshSession.command(f'oc start-build {name} --from-file={self.eNBSourceCodePath}', '\$', 300)
|
||||
before = sshSession.getBefore()
|
||||
regres = re.search(r'build.build.openshift.io/(?P<jobname>[a-zA-Z0-9\-]+) started', str(before))
|
||||
if ret != 0 or before.count('Uploading finished') != 1 or regres is None:
|
||||
logging.error("error during oc start-build: " + sshSession.getBefore())
|
||||
self._delete_pod(sshSession, name)
|
||||
ret = self.cmd.run(f'oc start-build {name} --from-file={self.eNBSourceCodePath}')
|
||||
regres = re.search(r'build.build.openshift.io/(?P<jobname>[a-zA-Z0-9\-]+) started', ret.stdout)
|
||||
if ret.returncode != 0 or ret.stdout.count('Uploading finished') != 1 or regres is None:
|
||||
logging.error(f"error during oc start-build: {ret.stdout}")
|
||||
return None
|
||||
return regres.group('jobname') + '-build'
|
||||
|
||||
def _delete_pod(self, sshSession, shortName):
|
||||
sshSession.command(f"oc get pods | grep {shortName}", '\$', 5)
|
||||
regres = re.search(rf'{shortName}-[0-9]+-build', sshSession.getBefore())
|
||||
if regres is not None:
|
||||
sshSession.command(f"oc delete pod {regres.group(0)}", '\$', 5)
|
||||
else:
|
||||
logging.warning(f"no pod found with name {shortName}")
|
||||
|
||||
def _wait_build_end(self, sshSession, jobs, timeout_sec, check_interval_sec = 5):
|
||||
def _wait_build_end(self, jobs, timeout_sec, check_interval_sec = 5):
|
||||
logging.debug(f"waiting for jobs {jobs} to finish building")
|
||||
while timeout_sec > 0:
|
||||
# check status
|
||||
for j in jobs:
|
||||
sshSession.command(f'oc get pods | grep {j}', '\$', 30, silent = True)
|
||||
if sshSession.getBefore().count('Completed') > 0: jobs.remove(j)
|
||||
if sshSession.getBefore().count('Error') > 0:
|
||||
logging.error(f'error for job {j}: ' + sshSession.getBefore())
|
||||
ret = self.cmd.run(f'oc get pods | grep {j}', silent = True)
|
||||
if ret.stdout.count('Completed') > 0: jobs.remove(j)
|
||||
if ret.stdout.count('Error') > 0:
|
||||
logging.error(f'error for job {j}: {ret.stdout}')
|
||||
return False
|
||||
if jobs == []:
|
||||
logging.debug('all jobs completed')
|
||||
@@ -147,44 +132,43 @@ class Cluster:
|
||||
logging.error(f"timeout while waiting for end of build of {jobs}")
|
||||
return False
|
||||
|
||||
def _retag_image_statement(self, sshSession, oldImage, newImage, newTag, filename):
|
||||
sshSession.command(f'sed -i -e "s#{oldImage}:latest#{newImage}:{newTag}#" {filename}', '\$', 5)
|
||||
def _retag_image_statement(self, oldImage, newImage, newTag, filename):
|
||||
self.cmd.run(f'sed -i -e "s#{oldImage}:latest#{newImage}:{newTag}#" {filename}')
|
||||
|
||||
def _get_image_size(self, sshSession, image, tag):
|
||||
def _get_image_size(self, image, tag):
|
||||
# get the SHA of the image we built using the image name and its tag
|
||||
sshSession.command(f'oc describe is {image} | grep -A4 {tag}', '\$', 5)
|
||||
result = re.search(f'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/(?P<imageSha>{image}@sha256:[a-f0-9]+)', sshSession.getBefore())
|
||||
ret = self.cmd.run(f'oc describe is {image} | grep -A4 {tag}')
|
||||
result = re.search(f'{IMAGE_REGISTRY_SERVICE_NAME}:5000/{NAMESPACE}/(?P<imageSha>{image}@sha256:[a-f0-9]+)', ret.stdout)
|
||||
if result is None:
|
||||
return -1
|
||||
imageSha = result.group("imageSha")
|
||||
|
||||
# retrieve the size
|
||||
sshSession.command(f'oc get -o json isimage {imageSha} | jq -Mc "{{dockerImageSize: .image.dockerImageMetadata.Size}}"', '\$', 5)
|
||||
result = re.search('{"dockerImageSize":(?P<size>[0-9]+)}', str(sshSession.getBefore()))
|
||||
ret = self.cmd.run(f'oc get -o json isimage {imageSha} | jq -Mc "{{dockerImageSize: .image.dockerImageMetadata.Size}}"')
|
||||
result = re.search('{"dockerImageSize":(?P<size>[0-9]+)}', ret.stdout)
|
||||
if result is None:
|
||||
return -1
|
||||
return int(result.group("size"))
|
||||
|
||||
def _deploy_pod(self, sshSession, filename, timeout = 30):
|
||||
sshSession.command(f'oc create -f {filename}', '\$', 10)
|
||||
result = re.search(f'pod/(?P<pod>[a-zA-Z0-9_\-]+) created', sshSession.getBefore())
|
||||
def _deploy_pod(self, filename, timeout = 30):
|
||||
ret = self.cmd.run(f'oc create -f {filename}')
|
||||
result = re.search(f'pod/(?P<pod>[a-zA-Z0-9_\-]+) created', ret.stdout)
|
||||
if result is None:
|
||||
logging.error(f'could not deploy pod: {sshSession.getBefore()}')
|
||||
logging.error(f'could not deploy pod: {ret.stdout}')
|
||||
return None
|
||||
pod = result.group("pod")
|
||||
logging.debug(f'checking if pod {pod} is in Running state')
|
||||
while timeout > 0:
|
||||
sshSession.command(f'oc get pod {pod} -o json | jq -Mc .status.phase', '\$', 5, silent=True)
|
||||
if re.search('"Running"', sshSession.getBefore()) is not None: return pod
|
||||
ret = self.cmd.run(f'oc get pod {pod} -o json | jq -Mc .status.phase', silent=True)
|
||||
if re.search('"Running"', ret.stdout) is not None: return pod
|
||||
timeout -= 1
|
||||
time.sleep(1)
|
||||
logging.error(f'pod {pod} did not reach Running state')
|
||||
self._undeploy_pod(sshSession, filename)
|
||||
self._undeploy_pod(filename)
|
||||
return None
|
||||
|
||||
def _undeploy_pod(self, sshSession, filename):
|
||||
# to save time we start this in the background and trust that oc stops correctly
|
||||
sshSession.command(f'oc delete -f {filename} &', '\$', 5)
|
||||
def _undeploy_pod(self, filename):
|
||||
self.cmd.run(f'oc delete -f {filename}')
|
||||
|
||||
def BuildClusterImage(self, HTML):
|
||||
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
|
||||
@@ -194,8 +178,7 @@ class Cluster:
|
||||
lIpAddr = self.eNBIPAddress
|
||||
lSourcePath = self.eNBSourceCodePath
|
||||
if lIpAddr == '' or lSourcePath == '':
|
||||
HELP.GenericHelp(CONST.Version)
|
||||
sys.exit('Insufficient Parameter: no SSH Credentials')
|
||||
sys.exit('Insufficient Parameter: eNBSourceCodePath missing')
|
||||
ocUserName = self.OCUserName
|
||||
ocPassword = self.OCPassword
|
||||
ocProjectName = self.OCProjectName
|
||||
@@ -206,29 +189,27 @@ class Cluster:
|
||||
sys.exit(f'ocRegistry {self.OCRegistry} should not start with http:// or https:// and end on a slash /')
|
||||
|
||||
logging.debug(f'Building on cluster triggered from server: {lIpAddr}')
|
||||
mySSH = SSH.SSHConnection()
|
||||
mySSH.open(lIpAddr, "oaicicd", "SHOULD NOT BE NECESSARY")
|
||||
self.cmd = cls_cmd.RemoteCmd(lIpAddr)
|
||||
|
||||
self.testCase_id = HTML.testCase_id
|
||||
|
||||
# Workaround for some servers, we need to erase completely the workspace
|
||||
if self.forcedWorkspaceCleanup:
|
||||
mySSH.command(f'rm -Rf {lSourcePath}', '\$', 15)
|
||||
cls_containerize.CreateWorkspace(mySSH, lSourcePath, self.ranRepository, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge)
|
||||
self.cmd.run(f'rm -Rf {lSourcePath}')
|
||||
cls_containerize.CreateWorkspace(self.cmd, lSourcePath, self.ranRepository, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge)
|
||||
|
||||
# we don't necessarily need a forced workspace cleanup, but in
|
||||
# order to reduce the amount of data send to OpenShift, we
|
||||
# to reduce the amount of data send to OpenShift, we
|
||||
# manually delete all generated files in the workspace
|
||||
mySSH.command(f'rm -rf {lSourcePath}/cmake_targets/ran_build', '\$', 30);
|
||||
self.cmd.run(f'rm -rf {lSourcePath}/cmake_targets/ran_build');
|
||||
|
||||
baseTag = 'develop'
|
||||
forceBaseImageBuild = False
|
||||
imageTag = 'develop'
|
||||
if self.ranAllowMerge: # merging MR branch into develop -> temporary image
|
||||
imageTag = 'ci-temp'
|
||||
imageTag = f'{self.ranBranch}-{self.ranCommitID[0:8]}'
|
||||
if self.ranTargetBranch == 'develop':
|
||||
mySSH.command(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base.rhel8.2 | grep --colour=never -i INDEX', '\$', 5)
|
||||
result = re.search('index', mySSH.getBefore())
|
||||
ret = self.cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base.rhel8.2 | grep --colour=never -i INDEX')
|
||||
result = re.search('index', ret.stdout)
|
||||
if result is not None:
|
||||
forceBaseImageBuild = True
|
||||
baseTag = 'ci-temp'
|
||||
@@ -236,122 +217,120 @@ class Cluster:
|
||||
forceBaseImageBuild = True
|
||||
|
||||
# logging to OC Cluster and then switch to corresponding project
|
||||
mySSH.command(f'oc login -u {ocUserName} -p {ocPassword} --server {self.OCUrl}', '\$', 31)
|
||||
if mySSH.getBefore().count('Login successful.') == 0:
|
||||
ret = self.cmd.run(f'oc login -u {ocUserName} -p {ocPassword} --server {self.OCUrl}')
|
||||
if ret.returncode != 0:
|
||||
logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m')
|
||||
mySSH.close()
|
||||
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL)
|
||||
return False
|
||||
|
||||
mySSH.command(f'oc project {ocProjectName}', '\$', 30)
|
||||
if mySSH.getBefore().count(f'Already on project "{ocProjectName}"') == 0 and mySSH.getBefore().count(f'Now using project "{self.OCProjectName}"') == 0:
|
||||
ret = self.cmd.run(f'oc project {ocProjectName}')
|
||||
if ret.returncode != 0:
|
||||
logging.error(f'\u001B[1mUnable to access OC project {ocProjectName}\u001B[0m')
|
||||
mySSH.command('oc logout', '\$', 30)
|
||||
mySSH.close()
|
||||
self.cmd.run('oc logout')
|
||||
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_PROJECT_FAIL)
|
||||
return False
|
||||
|
||||
self._recreate_entitlements(mySSH)
|
||||
self._recreate_entitlements()
|
||||
|
||||
status = True # flag to abandon compiling if any image fails
|
||||
attemptedImages = []
|
||||
if forceBaseImageBuild:
|
||||
self._recreate_is_tag(mySSH, 'ran-base', baseTag, 'openshift/ran-base-is.yaml')
|
||||
self._recreate_bc(mySSH, 'ran-base', baseTag, 'openshift/ran-base-bc.yaml')
|
||||
ranbase_job = self._start_build(mySSH, 'ran-base')
|
||||
self._recreate_is_tag('ran-base', baseTag, 'openshift/ran-base-is.yaml')
|
||||
self._recreate_bc('ran-base', baseTag, 'openshift/ran-base-bc.yaml')
|
||||
ranbase_job = self._start_build('ran-base')
|
||||
attemptedImages += ['ran-base']
|
||||
status = ranbase_job is not None and self._wait_build_end(mySSH, [ranbase_job], 600)
|
||||
status = ranbase_job is not None and self._wait_build_end([ranbase_job], 600)
|
||||
if not status: logging.error('failure during build of ran-base')
|
||||
mySSH.command(f'oc logs {ranbase_job} &> cmake_targets/log/ran-base.log', '\$', 10)
|
||||
self.cmd.run(f'oc logs {ranbase_job} &> cmake_targets/log/ran-base.log') # cannot use cmd.run because of redirect
|
||||
# recover logs by mounting image
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'ran-base', baseTag, 'openshift/ran-base-log-retrieval.yaml')
|
||||
pod = self._deploy_pod(mySSH, 'openshift/ran-base-log-retrieval.yaml')
|
||||
self._retag_image_statement('ran-base', 'ran-base', baseTag, 'openshift/ran-base-log-retrieval.yaml')
|
||||
pod = self._deploy_pod('openshift/ran-base-log-retrieval.yaml')
|
||||
if pod is not None:
|
||||
mySSH.command(f'mkdir -p cmake_targets/log/ran-base', '\$', 5)
|
||||
mySSH.command(f'oc rsync {pod}:/oai-ran/cmake_targets/log/ cmake_targets/log/ran-base', '\$', 5)
|
||||
self._undeploy_pod(mySSH, 'openshift/ran-base-log-retrieval.yaml')
|
||||
self.cmd.run(f'mkdir -p cmake_targets/log/ran-base')
|
||||
self.cmd.run(f'oc rsync {pod}:/oai-ran/cmake_targets/log/ cmake_targets/log/ran-base')
|
||||
self._undeploy_pod('openshift/ran-base-log-retrieval.yaml')
|
||||
else:
|
||||
status = False
|
||||
|
||||
if status:
|
||||
self._recreate_is_tag(mySSH, 'oai-physim', imageTag, 'openshift/oai-physim-is.yaml')
|
||||
self._recreate_bc(mySSH, 'oai-physim', imageTag, 'openshift/oai-physim-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.phySim.rhel8.2')
|
||||
physim_job = self._start_build(mySSH, 'oai-physim')
|
||||
self._recreate_is_tag('oai-physim', imageTag, 'openshift/oai-physim-is.yaml')
|
||||
self._recreate_bc('oai-physim', imageTag, 'openshift/oai-physim-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.phySim.rhel8.2')
|
||||
physim_job = self._start_build('oai-physim')
|
||||
attemptedImages += ['oai-physim']
|
||||
|
||||
self._recreate_is_tag(mySSH, 'ran-build', imageTag, 'openshift/ran-build-is.yaml')
|
||||
self._recreate_bc(mySSH, 'ran-build', imageTag, 'openshift/ran-build-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.build.rhel8.2')
|
||||
ranbuild_job = self._start_build(mySSH, 'ran-build')
|
||||
self._recreate_is_tag('ran-build', imageTag, 'openshift/ran-build-is.yaml')
|
||||
self._recreate_bc('ran-build', imageTag, 'openshift/ran-build-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.build.rhel8.2')
|
||||
ranbuild_job = self._start_build('ran-build')
|
||||
attemptedImages += ['ran-build']
|
||||
|
||||
wait = ranbuild_job is not None and physim_job is not None and self._wait_build_end(mySSH, [ranbuild_job, physim_job], 1200)
|
||||
wait = ranbuild_job is not None and physim_job is not None and self._wait_build_end([ranbuild_job, physim_job], 1200)
|
||||
if not wait: logging.error('error during build of ranbuild_job or physim_job')
|
||||
status = status and wait
|
||||
mySSH.command(f'oc logs {ranbuild_job} &> cmake_targets/log/ran-build.log', '\$', 10)
|
||||
mySSH.command(f'oc logs {physim_job} &> cmake_targets/log/oai-physim.log', '\$', 10)
|
||||
mySSH.command('oc get pods.metrics.k8s.io >> cmake_targets/log/build-metrics.log', '\$', 10)
|
||||
self.cmd.run(f'oc logs {ranbuild_job} &> cmake_targets/log/ran-build.log')
|
||||
self.cmd.run(f'oc logs {physim_job} &> cmake_targets/log/oai-physim.log')
|
||||
self.cmd.run(f'oc get pods.metrics.k8s.io &>> cmake_targets/log/build-metrics.log', '\$', 10)
|
||||
|
||||
if status:
|
||||
self._recreate_is_tag(mySSH, 'oai-enb', imageTag, 'openshift/oai-enb-is.yaml')
|
||||
self._recreate_bc(mySSH, 'oai-enb', imageTag, 'openshift/oai-enb-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.eNB.rhel8.2')
|
||||
self._retag_image_statement(mySSH, 'ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.eNB.rhel8.2')
|
||||
enb_job = self._start_build(mySSH, 'oai-enb')
|
||||
self._recreate_is_tag('oai-enb', imageTag, 'openshift/oai-enb-is.yaml')
|
||||
self._recreate_bc('oai-enb', imageTag, 'openshift/oai-enb-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.eNB.rhel8.2')
|
||||
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.eNB.rhel8.2')
|
||||
enb_job = self._start_build('oai-enb')
|
||||
attemptedImages += ['oai-enb']
|
||||
|
||||
self._recreate_is_tag(mySSH, 'oai-gnb', imageTag, 'openshift/oai-gnb-is.yaml')
|
||||
self._recreate_bc(mySSH, 'oai-gnb', imageTag, 'openshift/oai-gnb-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.rhel8.2')
|
||||
self._retag_image_statement(mySSH, 'ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.gNB.rhel8.2')
|
||||
gnb_job = self._start_build(mySSH, 'oai-gnb')
|
||||
self._recreate_is_tag('oai-gnb', imageTag, 'openshift/oai-gnb-is.yaml')
|
||||
self._recreate_bc('oai-gnb', imageTag, 'openshift/oai-gnb-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.rhel8.2')
|
||||
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.gNB.rhel8.2')
|
||||
gnb_job = self._start_build('oai-gnb')
|
||||
attemptedImages += ['oai-gnb']
|
||||
|
||||
self._recreate_is_tag(mySSH, 'oai-gnb-aw2s', imageTag, 'openshift/oai-gnb-aw2s-is.yaml')
|
||||
self._recreate_bc(mySSH, 'oai-gnb-aw2s', imageTag, 'openshift/oai-gnb-aw2s-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.aw2s.rhel8.2')
|
||||
self._retag_image_statement(mySSH, 'ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.gNB.aw2s.rhel8.2')
|
||||
gnb_aw2s_job = self._start_build(mySSH, 'oai-gnb-aw2s')
|
||||
self._recreate_is_tag('oai-gnb-aw2s', imageTag, 'openshift/oai-gnb-aw2s-is.yaml')
|
||||
self._recreate_bc('oai-gnb-aw2s', imageTag, 'openshift/oai-gnb-aw2s-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.aw2s.rhel8.2')
|
||||
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.gNB.aw2s.rhel8.2')
|
||||
gnb_aw2s_job = self._start_build('oai-gnb-aw2s')
|
||||
attemptedImages += ['oai-gnb-aw2s']
|
||||
|
||||
wait = enb_job is not None and gnb_job is not None and gnb_aw2s_job is not None and self._wait_build_end(mySSH, [enb_job, gnb_job, gnb_aw2s_job], 600)
|
||||
wait = enb_job is not None and gnb_job is not None and gnb_aw2s_job is not None and self._wait_build_end([enb_job, gnb_job, gnb_aw2s_job], 600)
|
||||
if not wait: logging.error('error during build of eNB/gNB')
|
||||
status = status and wait
|
||||
# recover logs
|
||||
mySSH.command(f'oc logs {enb_job} &> cmake_targets/log/oai-enb.log', '\$', 10)
|
||||
mySSH.command(f'oc logs {gnb_job} &> cmake_targets/log/oai-gnb.log', '\$', 10)
|
||||
mySSH.command(f'oc logs {gnb_aw2s_job} &> cmake_targets/log/oai-gnb-aw2s.log', '\$', 10)
|
||||
self.cmd.run(f'oc logs {enb_job} &> cmake_targets/log/oai-enb.log')
|
||||
self.cmd.run(f'oc logs {gnb_job} &> cmake_targets/log/oai-gnb.log')
|
||||
self.cmd.run(f'oc logs {gnb_aw2s_job} &> cmake_targets/log/oai-gnb-aw2s.log')
|
||||
|
||||
self._recreate_is_tag(mySSH, 'oai-lte-ue', imageTag, 'openshift/oai-lte-ue-is.yaml')
|
||||
self._recreate_bc(mySSH, 'oai-lte-ue', imageTag, 'openshift/oai-lte-ue-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.lteUE.rhel8.2')
|
||||
self._retag_image_statement(mySSH, 'ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.lteUE.rhel8.2')
|
||||
lteue_job = self._start_build(mySSH, 'oai-lte-ue')
|
||||
self._recreate_is_tag('oai-lte-ue', imageTag, 'openshift/oai-lte-ue-is.yaml')
|
||||
self._recreate_bc('oai-lte-ue', imageTag, 'openshift/oai-lte-ue-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.lteUE.rhel8.2')
|
||||
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.lteUE.rhel8.2')
|
||||
lteue_job = self._start_build('oai-lte-ue')
|
||||
attemptedImages += ['oai-lte-ue']
|
||||
|
||||
self._recreate_is_tag(mySSH, 'oai-nr-ue', imageTag, 'openshift/oai-nr-ue-is.yaml')
|
||||
self._recreate_bc(mySSH, 'oai-nr-ue', imageTag, 'openshift/oai-nr-ue-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.nrUE.rhel8.2')
|
||||
self._retag_image_statement(mySSH, 'ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.nrUE.rhel8.2')
|
||||
nrue_job = self._start_build(mySSH, 'oai-nr-ue')
|
||||
self._recreate_is_tag('oai-nr-ue', imageTag, 'openshift/oai-nr-ue-is.yaml')
|
||||
self._recreate_bc('oai-nr-ue', imageTag, 'openshift/oai-nr-ue-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.nrUE.rhel8.2')
|
||||
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.nrUE.rhel8.2')
|
||||
nrue_job = self._start_build('oai-nr-ue')
|
||||
attemptedImages += ['oai-nr-ue']
|
||||
|
||||
wait = lteue_job is not None and nrue_job is not None and self._wait_build_end(mySSH, [lteue_job, nrue_job], 600)
|
||||
wait = lteue_job is not None and nrue_job is not None and self._wait_build_end([lteue_job, nrue_job], 600)
|
||||
if not wait: logging.error('error during build of lteUE/nrUE')
|
||||
status = status and wait
|
||||
# recover logs
|
||||
mySSH.command(f'oc logs {lteue_job} &> cmake_targets/log/oai-lte-ue.log', '\$', 10)
|
||||
mySSH.command(f'oc logs {nrue_job} &> cmake_targets/log/oai-nr-ue.log', '\$', 10)
|
||||
mySSH.command('oc get pods.metrics.k8s.io >> cmake_targets/log/build-metrics.log', '\$', 10)
|
||||
self.cmd.run(f'oc logs {lteue_job} &> cmake_targets/log/oai-lte-ue.log')
|
||||
self.cmd.run(f'oc logs {nrue_job} &> cmake_targets/log/oai-nr-ue.log')
|
||||
self.cmd.run(f'oc get pods.metrics.k8s.io &>> cmake_targets/log/build-metrics.log', '\$', 10)
|
||||
|
||||
# split and analyze logs
|
||||
imageSize = {}
|
||||
for image in attemptedImages:
|
||||
mySSH.command(f'mkdir -p cmake_targets/log/{image}', '\$', 5)
|
||||
mySSH.command(f'python3 ci-scripts/docker_log_split.py --logfilename=cmake_targets/log/{image}.log', '\$', 5)
|
||||
self.cmd.run(f'mkdir -p cmake_targets/log/{image}')
|
||||
self.cmd.run(f'python3 ci-scripts/docker_log_split.py --logfilename=cmake_targets/log/{image}.log')
|
||||
tag = imageTag if image != 'ran-base' else baseTag
|
||||
size = self._get_image_size(mySSH, image, tag)
|
||||
size = self._get_image_size(image, tag)
|
||||
if size <= 0:
|
||||
imageSize[image] = 'unknown -- BUILD FAILED'
|
||||
status = False
|
||||
@@ -361,17 +340,17 @@ class Cluster:
|
||||
logging.info(f'\u001B[1m{image} size is {imageSize[image]}\u001B[0m')
|
||||
|
||||
grep_exp = "\|".join(attemptedImages)
|
||||
mySSH.command(f'oc get images | grep -e \'{grep_exp}\' &> cmake_targets/log/image_registry.log', '\$', 10);
|
||||
mySSH.command('for pod in $(oc get pods | tail -n +2 | awk \'{print $1}\'); do oc get pod $pod -o json >> cmake_targets/log/build_pod_summary.log; done', '\$', 60)
|
||||
self.cmd.run(f'oc get images | grep -e \'{grep_exp}\' &> cmake_targets/log/image_registry.log');
|
||||
self.cmd.run(f'for pod in $(oc get pods | tail -n +2 | awk \'{{print $1}}\'); do oc get pod $pod -o json &>> cmake_targets/log/build_pod_summary.log; done', '\$', 60)
|
||||
|
||||
build_log_name = f'build_log_{self.testCase_id}'
|
||||
cls_containerize.CopyLogsToExecutor(mySSH, lSourcePath, build_log_name, lIpAddr, 'oaicicd', CONST.CI_NO_PASSWORD)
|
||||
cls_containerize.CopyLogsToExecutor(self.cmd, lSourcePath, build_log_name)
|
||||
|
||||
mySSH.command('for pod in $(oc get pods | tail -n +2 | awk \'{print $1}\'); do oc delete pod ${pod}; done', '\$', 60)
|
||||
self.cmd.run('for pod in $(oc get pods | tail -n +2 | awk \'{print $1}\'); do oc delete pod ${pod}; done')
|
||||
|
||||
# logout will return eventually, but we don't care when -> start in background
|
||||
mySSH.command('oc logout &', '\$', 5)
|
||||
mySSH.close()
|
||||
self.cmd.run(f'oc logout')
|
||||
self.cmd.close()
|
||||
|
||||
# Analyze the logs
|
||||
collectInfo = cls_containerize.AnalyzeBuildLogs(build_log_name, attemptedImages, status)
|
||||
|
||||
217
ci-scripts/cls_cmd.py
Normal file
217
ci-scripts/cls_cmd.py
Normal file
@@ -0,0 +1,217 @@
|
||||
#/*
|
||||
# * 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
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
#
|
||||
# Required Python Version
|
||||
# Python 3.x
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
import abc
|
||||
import logging
|
||||
import subprocess as sp
|
||||
import os
|
||||
import paramiko
|
||||
import uuid
|
||||
|
||||
# provides a partial interface for the legacy SSHconnection class (getBefore(), command())
|
||||
class Cmd(metaclass=abc.ABCMeta):
|
||||
def cd(self, d, silent=False):
|
||||
if d == None or d == '' or d == []:
|
||||
self.cwd = None
|
||||
elif d[0] == '/':
|
||||
self.cwd = d
|
||||
else:
|
||||
if not self.cwd:
|
||||
# no cwd set: get current working directory
|
||||
self.cwd = self.run('pwd').stdout.strip()
|
||||
self.cwd += f"/{d}"
|
||||
if not silent:
|
||||
logging.debug(f'cd {self.cwd}')
|
||||
|
||||
@abc.abstractmethod
|
||||
def run(self, line, timeout=300, silent=False):
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def command(self, commandline, expectedline, timeout, silent=False, resync=False):
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def close(self):
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def getBefore(self):
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def copyin(self, scpIp, scpUser, scpPw, src, tgt):
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def copyout(self, scpIp, scpUser, scpPw, src, tgt):
|
||||
return
|
||||
|
||||
class LocalCmd(Cmd):
|
||||
def __init__(self, d = None):
|
||||
self.cwd = d
|
||||
self.cp = sp.CompletedProcess(args='', returncode=0, stdout='')
|
||||
|
||||
def run(self, line, timeout=300, silent=False, reportNonZero=True):
|
||||
if type(line) is str:
|
||||
line = [s for s in line.split(' ') if len(s) > 0]
|
||||
if not silent:
|
||||
logging.debug(' '.join(line))
|
||||
try:
|
||||
ret = sp.run(line, cwd=self.cwd, stdout=sp.PIPE, stderr=sp.STDOUT, timeout=timeout)
|
||||
except Exception as e:
|
||||
ret = sp.CompletedProcess(args=line, returncode=255, stdout=f'Exception: {str(e)}'.encode('utf-8'))
|
||||
if ret.stdout is None:
|
||||
ret.stdout = b''
|
||||
ret.stdout = ret.stdout.decode('utf-8').strip()
|
||||
if reportNonZero and ret.returncode != 0:
|
||||
cmd = ' '.join(ret.args)
|
||||
logging.warning(f'command "{cmd}" returned non-zero returncode {ret.returncode}: output:\n{ret.stdout}')
|
||||
self.cp = ret
|
||||
return ret
|
||||
|
||||
def command(self, commandline, expectedline=None, timeout=300, silent=False, resync=False):
|
||||
line = [s for s in commandline.split(' ') if len(s) > 0]
|
||||
if line[0] == 'cd':
|
||||
self.cd(line[1], silent)
|
||||
else:
|
||||
self.run(line, timeout, silent)
|
||||
return 0
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
def getBefore(self):
|
||||
return self.cp.stdout
|
||||
|
||||
def copyin(self, scpIp, scpUser, scpPw, src, tgt):
|
||||
logging.warning("LocalCmd emulating sshconnection.copyin() function")
|
||||
self.run(f'cp -r {src} {tgt}')
|
||||
|
||||
def copyout(self, scpIp, scpUser, scpPw, src, tgt):
|
||||
logging.warning("LocalCmd emulating sshconnection.copyout() function")
|
||||
self.run(f'cp -r {src} {tgt}')
|
||||
|
||||
class RemoteCmd(Cmd):
|
||||
def __init__(self, hostname, d=None):
|
||||
logging.getLogger('paramiko').setLevel(logging.INFO) # prevent spamming through Paramiko
|
||||
self.client = paramiko.SSHClient()
|
||||
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
cfg = RemoteCmd._lookup_ssh_config(hostname)
|
||||
self.client.connect(**cfg)
|
||||
self.cwd = d
|
||||
self.cp = sp.CompletedProcess(args='', returncode=0, stdout='')
|
||||
|
||||
def _lookup_ssh_config(hostname):
|
||||
ssh_config = paramiko.SSHConfig()
|
||||
user_config_file = os.path.expanduser("~/.ssh/config")
|
||||
if os.path.exists(user_config_file):
|
||||
with open(user_config_file) as f:
|
||||
ssh_config.parse(f)
|
||||
else:
|
||||
raise FileNotFoundError('class needs SSH config at ~/.ssh/config')
|
||||
ucfg = ssh_config.lookup(hostname)
|
||||
if 'identityfile' not in ucfg or 'user' not in ucfg:
|
||||
raise KeyError(f'no identityfile or user in SSH config for host {hostname}')
|
||||
cfg = {'hostname':hostname, 'username':ucfg['user'], 'key_filename':ucfg['identityfile']}
|
||||
if 'hostname' in ucfg:
|
||||
cfg['hostname'] = ucfg['hostname'] # override user-given hostname with what is in config
|
||||
if 'port' in ucfg:
|
||||
cfg['port'] = int(ucfg['port'])
|
||||
if 'proxycommand' in ucfg:
|
||||
cfg['sock'] = paramiko.ProxyCommand(ucfg['proxycommand'])
|
||||
return cfg
|
||||
|
||||
def run(self, line, timeout=300, silent=False, reportNonZero=True):
|
||||
if type(line) is list:
|
||||
line = ' '.join(line)
|
||||
if not silent:
|
||||
logging.debug(line)
|
||||
if self.cwd:
|
||||
line = f"cd {self.cwd} && {line}"
|
||||
args = line.split(' ')
|
||||
try:
|
||||
stdin, stdout, stderr = self.client.exec_command(line, timeout=timeout)
|
||||
ret = sp.CompletedProcess(args=args, returncode=stdout.channel.recv_exit_status(), stdout=stdout.read(size=None) + stderr.read(size=None))
|
||||
except Exception as e:
|
||||
ret = sp.CompletedProcess(args=args, returncode=255, stdout=f'Exception: {str(e)}'.encode('utf-8'))
|
||||
ret.stdout = ret.stdout.decode('utf-8').strip()
|
||||
if reportNonZero and ret.returncode != 0:
|
||||
cmd = ' '.join(ret.args)
|
||||
logging.warning(f'command "{cmd}" returned non-zero returncode {ret.returncode}: output:\n{ret.stdout}')
|
||||
self.cp = ret
|
||||
return ret
|
||||
|
||||
def command(self, commandline, expectedline=None, timeout=300, silent=False, resync=False):
|
||||
line = [s for s in commandline.split(' ') if len(s) > 0]
|
||||
if line[0] == 'cd':
|
||||
self.cd(line[1], silent)
|
||||
else:
|
||||
self.run(line, timeout, silent)
|
||||
return 0
|
||||
|
||||
def close(self):
|
||||
self.client.close()
|
||||
|
||||
def getBefore(self):
|
||||
return self.cp.stdout
|
||||
|
||||
def copyout(self, src, tgt, recursive=False):
|
||||
logging.warning("RemoteCmd emulating sshconnection.copyout() function, ignoring scpIp")
|
||||
logging.debug(f"copyout: local:{src} -> remote:{tgt}")
|
||||
if recursive:
|
||||
tmpfile = f"{uuid.uuid4()}.tar"
|
||||
abstmpfile = f"/tmp/{tmpfile}"
|
||||
cmd = LocalCmd()
|
||||
cmd.run(f"tar -cf {abstmpfile} {src}")
|
||||
sftp = self.client.open_sftp()
|
||||
sftp.put(abstmpfile, abstmpfile)
|
||||
sftp.close()
|
||||
cmd.run(f"rm {abstmpfile}")
|
||||
self.run(f"mv {abstmpfile} {tgt}; cd {tgt} && tar -xf {tmpfile} && rm {tmpfile}")
|
||||
else:
|
||||
sftp = self.client.open_sftp()
|
||||
sftp.put(src, tgt)
|
||||
sftp.close()
|
||||
|
||||
def copyin(self, src, tgt, recursive=False):
|
||||
logging.warning("RemoteCmd emulating sshconnection.copyout() function")
|
||||
logging.debug(f"copyin: remote:{src} -> local:{tgt}")
|
||||
if recursive:
|
||||
tmpfile = f"{uuid.uuid4()}.tar"
|
||||
abstmpfile = f"/tmp/{tmpfile}"
|
||||
self.run(f"tar -cf {abstmpfile} {src}")
|
||||
sftp = self.client.open_sftp()
|
||||
sftp.get(abstmpfile, abstmpfile)
|
||||
sftp.close()
|
||||
self.run(f"rm {abstmpfile}")
|
||||
cmd = LocalCmd()
|
||||
cmd.run(f"mv {abstmpfile} {tgt}; cd {tgt} && tar -xf {tmpfile} && rm {tmpfile}")
|
||||
else:
|
||||
sftp = self.client.open_sftp()
|
||||
sftp.get(src, tgt)
|
||||
sftp.close()
|
||||
@@ -44,6 +44,7 @@ from zipfile import ZipFile
|
||||
#-----------------------------------------------------------
|
||||
# OAI Testing modules
|
||||
#-----------------------------------------------------------
|
||||
import cls_cmd
|
||||
import sshconnection as SSH
|
||||
import helpreadme as HELP
|
||||
import constants as CONST
|
||||
@@ -83,20 +84,20 @@ def CreateWorkspace(sshSession, sourcePath, ranRepository, ranCommitID, ranTarge
|
||||
logging.debug(f'Merging with the target branch: {ranTargetBranch}')
|
||||
sshSession.command(f'git merge --ff origin/{ranTargetBranch} -m "Temporary merge for CI"', '\$', 30)
|
||||
|
||||
def CopyLogsToExecutor(sshSession, sourcePath, log_name, scpIp, scpUser, scpPw):
|
||||
sshSession.command(f'cd {sourcePath}/cmake_targets', '\$', 5)
|
||||
sshSession.command(f'rm -f {log_name}.zip', '\$', 5)
|
||||
sshSession.command(f'mkdir -p {log_name}', '\$', 5)
|
||||
sshSession.command(f'mv log/* {log_name}', '\$', 5)
|
||||
sshSession.command(f'zip -r -qq {log_name}.zip {log_name}', '\$', 5)
|
||||
def CopyLogsToExecutor(cmd, sourcePath, log_name):
|
||||
cmd.cd(f'{sourcePath}/cmake_targets')
|
||||
cmd.run(f'rm -f {log_name}.zip')
|
||||
cmd.run(f'mkdir -p {log_name}')
|
||||
cmd.run(f'mv log/* {log_name}')
|
||||
cmd.run(f'zip -r -qq {log_name}.zip {log_name}')
|
||||
|
||||
# copy zip to executor for analysis
|
||||
if (os.path.isfile(f'./{log_name}.zip')):
|
||||
os.remove(f'./{log_name}.zip')
|
||||
if (os.path.isdir(f'./{log_name}')):
|
||||
shutil.rmtree(f'./{log_name}')
|
||||
sshSession.copyin(scpIp, scpUser, scpPw, f'{sourcePath}/cmake_targets/{log_name}.zip', '.')
|
||||
sshSession.command(f'rm -f {log_name}.zip','\$', 5)
|
||||
cmd.copyin(f'{sourcePath}/cmake_targets/{log_name}.zip', f'./{log_name}.zip')
|
||||
cmd.run(f'rm -f {log_name}.zip')
|
||||
ZipFile(f'{log_name}.zip').extractall('.')
|
||||
|
||||
def AnalyzeBuildLogs(buildRoot, images, globalStatus):
|
||||
@@ -329,12 +330,11 @@ class Containerize():
|
||||
HELP.GenericHelp(CONST.Version)
|
||||
sys.exit('Insufficient Parameter')
|
||||
logging.debug('Building on server: ' + lIpAddr)
|
||||
mySSH = SSH.SSHConnection()
|
||||
mySSH.open(lIpAddr, lUserName, lPassWord)
|
||||
cmd = cls_cmd.RemoteCmd(lIpAddr)
|
||||
|
||||
# Checking the hostname to get adapted on cli and dockerfileprefixes
|
||||
mySSH.command('hostnamectl', '\$', 5)
|
||||
result = re.search('Ubuntu|Red Hat', mySSH.getBefore())
|
||||
cmd.run('hostnamectl')
|
||||
result = re.search('Ubuntu|Red Hat', cmd.getBefore())
|
||||
self.host = result.group(0)
|
||||
if self.host == 'Ubuntu':
|
||||
self.cli = 'docker'
|
||||
@@ -369,18 +369,18 @@ class Containerize():
|
||||
|
||||
# Workaround for some servers, we need to erase completely the workspace
|
||||
if self.forcedWorkspaceCleanup:
|
||||
mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15)
|
||||
cmd.run(f'sudo -S rm -Rf {lSourcePath}')
|
||||
|
||||
self.testCase_id = HTML.testCase_id
|
||||
|
||||
CreateWorkspace(mySSH, lSourcePath, self.ranRepository, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge)
|
||||
CreateWorkspace(cmd, lSourcePath, self.ranRepository, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge)
|
||||
|
||||
# if asterix, copy the entitlement and subscription manager configurations
|
||||
if self.host == 'Red Hat':
|
||||
mySSH.command('mkdir -p ./etc-pki-entitlement ./rhsm-conf ./rhsm-ca', '\$', 5)
|
||||
mySSH.command('sudo cp /etc/rhsm/rhsm.conf ./rhsm-conf/', '\$', 5)
|
||||
mySSH.command('sudo cp /etc/rhsm/ca/redhat-uep.pem ./rhsm-ca/', '\$', 5)
|
||||
mySSH.command('sudo cp /etc/pki/entitlement/*.pem ./etc-pki-entitlement/', '\$', 5)
|
||||
cmd.run('mkdir -p ./etc-pki-entitlement ./rhsm-conf ./rhsm-ca')
|
||||
cmd.run('cp /etc/rhsm/rhsm.conf ./rhsm-conf/')
|
||||
cmd.run('cp /etc/rhsm/ca/redhat-uep.pem ./rhsm-ca/')
|
||||
cmd.run('cp /etc/pki/entitlement/*.pem ./etc-pki-entitlement/')
|
||||
|
||||
baseImage = 'ran-base'
|
||||
baseTag = 'develop'
|
||||
@@ -389,8 +389,8 @@ class Containerize():
|
||||
if (self.ranAllowMerge):
|
||||
imageTag = 'ci-temp'
|
||||
if self.ranTargetBranch == 'develop':
|
||||
mySSH.command('git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base' + self.dockerfileprefix + ' | grep --colour=never -i INDEX', '\$', 5)
|
||||
result = re.search('index', mySSH.getBefore())
|
||||
cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base{self.dockerfileprefix} | grep --colour=never -i INDEX')
|
||||
result = re.search('index', cmd.getBefore())
|
||||
if result is not None:
|
||||
forceBaseImageBuild = True
|
||||
baseTag = 'ci-temp'
|
||||
@@ -398,31 +398,31 @@ class Containerize():
|
||||
forceBaseImageBuild = True
|
||||
|
||||
# Let's remove any previous run artifacts if still there
|
||||
mySSH.command(self.cli + ' image prune --force', '\$', 30)
|
||||
cmd.run(f"{self.cli} image prune --force")
|
||||
if forceBaseImageBuild:
|
||||
mySSH.command(self.cli + ' image rm ' + baseImage + ':' + baseTag + ' || true', '\$', 30)
|
||||
cmd.run(f"{self.cli} image rm {baseImage}:{baseTag}")
|
||||
for image,pattern in imageNames:
|
||||
mySSH.command(self.cli + ' image rm ' + image + ':' + imageTag + ' || true', '\$', 30)
|
||||
cmd.run(f"{self.cli} image rm {image}:{imageTag}")
|
||||
|
||||
# Build the base image only on Push Events (not on Merge Requests)
|
||||
# On when the base image docker file is being modified.
|
||||
if forceBaseImageBuild:
|
||||
mySSH.command(self.cli + ' build ' + self.cliBuildOptions + ' --target ' + baseImage + ' --tag ' + baseImage + ':' + baseTag + ' --file docker/Dockerfile.base' + self.dockerfileprefix + ' . > cmake_targets/log/ran-base.log 2>&1', '\$', 1600)
|
||||
cmd.run(f"{self.cli} build {self.cliBuildOptions} --target {baseImage} --tag {baseImage}:{baseTag} --file docker/Dockerfile.base{self.dockerfileprefix} . &> cmake_targets/log/ran-base.log", timeout=1600)
|
||||
# First verify if the base image was properly created.
|
||||
mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' ' + baseImage + ':' + baseTag, '\$', 5)
|
||||
ret = cmd.run(f"{self.cli} image inspect --format=\'Size = {{{{.Size}}}} bytes\' {baseImage}:{baseTag}")
|
||||
allImagesSize = {}
|
||||
if mySSH.getBefore().count('o such image') != 0:
|
||||
if ret.returncode != 0:
|
||||
logging.error('\u001B[1m Could not build properly ran-base\u001B[0m')
|
||||
# Recover the name of the failed container?
|
||||
mySSH.command(self.cli + ' ps --quiet --filter "status=exited" -n1 | xargs ' + self.cli + ' rm -f', '\$', 5)
|
||||
mySSH.command(self.cli + ' image prune --force', '\$', 30)
|
||||
mySSH.close()
|
||||
cmd.run(f"{self.cli} ps --quiet --filter \"status=exited\" -n1 | xargs {self.cli} rm -f")
|
||||
cmd.run(f"{self.cli} image prune --force")
|
||||
cmd.close()
|
||||
logging.error('\u001B[1m Building OAI Images Failed\u001B[0m')
|
||||
HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK)
|
||||
HTML.CreateHtmlTabFooter(False)
|
||||
sys.exit(1)
|
||||
else:
|
||||
result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', mySSH.getBefore())
|
||||
result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', cmd.getBefore())
|
||||
if result is not None:
|
||||
size = float(result.group("size")) / 1000000
|
||||
imageSizeStr = f'{size:.1f}'
|
||||
@@ -432,10 +432,10 @@ class Containerize():
|
||||
logging.debug('ran-base size is unknown')
|
||||
|
||||
# Recover build logs, for the moment only possible when build is successful
|
||||
mySSH.command(self.cli + ' create --name test ' + baseImage + ':' + baseTag, '\$', 5)
|
||||
mySSH.command('mkdir -p cmake_targets/log/ran-base', '\$', 5)
|
||||
mySSH.command(self.cli + ' cp test:/oai-ran/cmake_targets/log/. cmake_targets/log/ran-base', '\$', 5)
|
||||
mySSH.command(self.cli + ' rm -f test', '\$', 5)
|
||||
cmd.run(f"{self.cli} create --name test {baseImage}:{baseTag}")
|
||||
cmd.run("mkdir -p cmake_targets/log/ran-base")
|
||||
cmd.run(f"{self.cli} cp test:/oai-ran/cmake_targets/log/. cmake_targets/log/ran-base")
|
||||
cmd.run(f"{self.cli} rm -f test")
|
||||
|
||||
# Build the target image(s)
|
||||
status = True
|
||||
@@ -444,26 +444,26 @@ class Containerize():
|
||||
attemptedImages += [image]
|
||||
# the archived Dockerfiles have "ran-base:latest" as base image
|
||||
# we need to update them with proper tag
|
||||
mySSH.command(f'sed -i -e "s#{baseImage}:latest#{baseImage}:{baseTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}', '\$', 5)
|
||||
cmd.run(f'sed -i -e "s#{baseImage}:latest#{baseImage}:{baseTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
|
||||
if image != 'ran-build':
|
||||
mySSH.command(f'sed -i -e "s#ran-build:latest#ran-build:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}', '\$', 5)
|
||||
mySSH.command(f'{self.cli} build {self.cliBuildOptions} --target {image} --tag {image}:{imageTag} --file docker/Dockerfile.{pattern}{self.dockerfileprefix} . > cmake_targets/log/{image}.log 2>&1', '\$', 1200)
|
||||
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
|
||||
cmd.run(f'{self.cli} build {self.cliBuildOptions} --target {image} --tag {image}:{imageTag} --file docker/Dockerfile.{pattern}{self.dockerfileprefix} . > cmake_targets/log/{image}.log 2>&1', timeout=1200)
|
||||
# split the log
|
||||
mySSH.command('mkdir -p cmake_targets/log/' + image, '\$', 5)
|
||||
mySSH.command('python3 ci-scripts/docker_log_split.py --logfilename=cmake_targets/log/' + image + '.log', '\$', 5)
|
||||
# checking the status of the build
|
||||
mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' ' + image + ':' + imageTag, '\$', 5)
|
||||
if mySSH.getBefore().count('o such image') != 0:
|
||||
cmd.run(f"mkdir -p cmake_targets/log/{image}")
|
||||
cmd.run(f"python3 ci-scripts/docker_log_split.py --logfilename=cmake_targets/log/{image}.log")
|
||||
# check the status of the build
|
||||
ret = cmd.run(f"{self.cli} image inspect --format=\'Size = {{{{.Size}}}} bytes\' {image}:{imageTag}")
|
||||
if ret.returncode != 0:
|
||||
logging.error('\u001B[1m Could not build properly ' + image + '\u001B[0m')
|
||||
status = False
|
||||
# Here we should check if the last container corresponds to a failed command and destroy it
|
||||
mySSH.command(self.cli + ' ps --quiet --filter "status=exited" -n1 | xargs ' + self.cli + ' rm -f', '\$', 5)
|
||||
cmd.run(f"{self.cli} ps --quiet --filter \"status=exited\" -n1 | xargs {self.cli} rm -f")
|
||||
allImagesSize[image] = 'N/A -- Build Failed'
|
||||
break
|
||||
else:
|
||||
result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', mySSH.getBefore())
|
||||
result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', cmd.getBefore())
|
||||
if result is not None:
|
||||
size = float(result.group("size")) / 1000000
|
||||
size = float(result.group("size")) / 1000000 # convert to MB
|
||||
imageSizeStr = f'{size:.1f}'
|
||||
logging.debug(f'\u001B[1m {image} size is {imageSizeStr} Mbytes\u001B[0m')
|
||||
allImagesSize[image] = f'{imageSizeStr} Mbytes'
|
||||
@@ -471,18 +471,18 @@ class Containerize():
|
||||
logging.debug(f'{image} size is unknown')
|
||||
allImagesSize[image] = 'unknown'
|
||||
# Now pruning dangling images in between target builds
|
||||
mySSH.command(self.cli + ' image prune --force', '\$', 30)
|
||||
cmd.run(f"{self.cli} image prune --force")
|
||||
|
||||
# Remove all intermediate build images and clean up
|
||||
if self.ranAllowMerge and forceBaseImageBuild:
|
||||
mySSH.command(f'{self.cli} image rm {baseImage}:{baseTag} || true', '\$', 30)
|
||||
mySSH.command(f'{self.cli} image rm ran-build:{imageTag}','\$', 30)
|
||||
mySSH.command(f'{self.cli} volume prune --force','\$', 15)
|
||||
cmd.run(f"{self.cli} image rm {baseImage}:{baseTag}")
|
||||
cmd.run(f"{self.cli} image rm ran-build:{imageTag}")
|
||||
cmd.run(f"{self.cli} volume prune --force")
|
||||
|
||||
# create a zip with all logs
|
||||
build_log_name = f'build_log_{self.testCase_id}'
|
||||
CopyLogsToExecutor(mySSH, lSourcePath, build_log_name, lIpAddr, lUserName, lPassWord)
|
||||
mySSH.close()
|
||||
CopyLogsToExecutor(cmd, lSourcePath, build_log_name)
|
||||
cmd.close()
|
||||
|
||||
# Analyze the logs
|
||||
collectInfo = AnalyzeBuildLogs(build_log_name, attemptedImages, status)
|
||||
@@ -1001,7 +1001,7 @@ class Containerize():
|
||||
services.append(s)
|
||||
logging.info(f'stopping services {services}')
|
||||
|
||||
mySSH.command(f'docker-compose -f ci-docker-compose.yml stop', '\$', 30)
|
||||
mySSH.command(f'docker-compose -f ci-docker-compose.yml stop -t3', '\$', 30)
|
||||
time.sleep(5) # give some time to running containers to stop
|
||||
for svcName in services:
|
||||
# head -n -1 suppresses the final "X exited with status code Y"
|
||||
@@ -1203,7 +1203,7 @@ class Containerize():
|
||||
|
||||
# Stop the containers to shut down objects
|
||||
logging.debug('\u001B[1m Stopping containers \u001B[0m')
|
||||
cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml stop'
|
||||
cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml stop -t3'
|
||||
logging.info(cmd)
|
||||
try:
|
||||
deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100)
|
||||
|
||||
@@ -193,6 +193,7 @@ class OaiCiTest():
|
||||
self.expectedNbOfConnectedUEs = 0
|
||||
self.ue_id = '' #used for module identification
|
||||
self.ue_trace ='' #used to enable QLog trace for Module UE, passed to Module UE object at InitializeUE()
|
||||
self.cmd_prefix = '' # prefix before {lte,nr}-uesoftmodem
|
||||
|
||||
|
||||
def BuildOAIUE(self,HTML):
|
||||
@@ -489,7 +490,7 @@ class OaiCiTest():
|
||||
copyin_res = SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/reconfig.raw', '.')
|
||||
if (copyin_res == 0):
|
||||
SSH.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, './reconfig.raw', self.UESourceCodePath + '/cmake_targets/ran_build/build')
|
||||
SSH.command('echo "ulimit -c unlimited && ./'+ self.air_interface +' ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
|
||||
SSH.command(f'echo "ulimit -c unlimited && {self.cmd_prefix} ./{self.air_interface} {self.Initialize_OAI_UE_args}" > ./my-lte-uesoftmodem-run{self.UE_instance}.sh', '\$', 5)
|
||||
SSH.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
|
||||
SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
|
||||
self.UELogFile = 'ue_' + self.testCase_id + '.log'
|
||||
|
||||
@@ -32,13 +32,14 @@
|
||||
# Import
|
||||
#-----------------------------------------------------------
|
||||
import logging
|
||||
import sshconnection as SSH
|
||||
import cls_oai_html
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import sshconnection as SSH
|
||||
import cls_oai_html
|
||||
import constants as CONST
|
||||
import helpreadme as HELP
|
||||
|
||||
@@ -105,7 +106,7 @@ class PhySim:
|
||||
if self.ranCommitID != '':
|
||||
mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
|
||||
if self.ranAllowMerge:
|
||||
imageTag = "ci-temp"
|
||||
imageTag = f'{self.ranBranch}-{self.ranCommitID[0:8]}'
|
||||
if self.ranTargetBranch == '':
|
||||
if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'):
|
||||
mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 30)
|
||||
|
||||
284
ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf
Normal file
284
ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf
Normal file
@@ -0,0 +1,284 @@
|
||||
Active_gNBs = ( "5G-GOA-gNB");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_name = "5G-GOA-gNB";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1 }) });
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
sib1_tda = 5;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 2;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 2150 MHz + 14 PRBs@15kHz SCS (same as initial BWP), points to Subcarrier 0 of RB#10 of SSB block
|
||||
absoluteFrequencySSB = 430504;
|
||||
dl_frequencyBand = 66;
|
||||
# this is 2150 MHz
|
||||
dl_absoluteFrequencyPointA = 430000;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 0;
|
||||
dl_carrierBandwidth = 25;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=0,L=25 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 6600;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 0;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 2;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 66;
|
||||
# this is 1750 MHz
|
||||
ul_absoluteFrequencyPointA = 350000;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 0;
|
||||
ul_carrierBandwidth = 25;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 6600;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 0;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 98;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 13;
|
||||
preambleReceivedTargetPower = -118;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 6;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 4;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 0;
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0;
|
||||
|
||||
msg3_DeltaPreamble = 1;
|
||||
p0_NominalWithGrant =-90;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -90;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 0;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 0;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 6;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "192.168.71.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "eno1";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/26";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "eno1";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/26";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 150;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 120;
|
||||
pucch0_dtx_threshold = 150;
|
||||
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "yes";
|
||||
nb_tx = 1;
|
||||
nb_rx = 1;
|
||||
att_tx = 0;
|
||||
att_rx = 0;
|
||||
bands = [7];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
sf_extension = 0;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
sdr_addrs = "type=x300";
|
||||
clock_src = "internal";
|
||||
# if_freq = 3700000000L;
|
||||
# if_offset = 1000000;
|
||||
}
|
||||
);
|
||||
|
||||
THREAD_STRUCT = (
|
||||
{
|
||||
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_DISABLE";
|
||||
}
|
||||
);
|
||||
|
||||
rfsimulator :
|
||||
{
|
||||
serveraddr = "server";
|
||||
serverport = "4043";
|
||||
options = (); #("saviq"); or/and "chanmod"
|
||||
modelname = "AWGN";
|
||||
IQfile = "/tmp/rfsimulator.iqs";
|
||||
};
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
f1ap_log_level ="debug";
|
||||
};
|
||||
335
ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf
Normal file
335
ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf
Normal file
@@ -0,0 +1,335 @@
|
||||
Active_gNBs = ( "gNB-OAI");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_name = "gNB-OAI";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1 }) });
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 1;
|
||||
min_rxtxtime = 5;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68
|
||||
absoluteFrequencySSB = 621312; # 641280
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3300.60 MHz
|
||||
dl_absoluteFrequencyPointA = 620040; # 640008
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 106;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=27,L=48 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 12;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 106;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 28875;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 98;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 12;
|
||||
preambleReceivedTargetPower = -96;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 6;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 4;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
msg3_DeltaPreamble = 1;
|
||||
p0_NominalWithGrant =-90;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -70;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 6;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
# Dedicated Serving Cell Configuration
|
||||
servingCellConfigDedicated = ({
|
||||
# BWP-Downlink
|
||||
# BWP 1 Configuration
|
||||
dl_bwp-Id_1 = 1;
|
||||
dl_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW)
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_bwp1_subcarrierSpacing = 1;
|
||||
|
||||
# BWP 2 Configuration
|
||||
dl_bwp-Id_2 = 2;
|
||||
dl_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW)
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_bwp2_subcarrierSpacing = 1;
|
||||
|
||||
# BWP 3 Configuration
|
||||
dl_bwp-Id_3 = 3;
|
||||
dl_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW)
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_bwp3_subcarrierSpacing = 1;
|
||||
|
||||
firstActiveDownlinkBWP-Id = 1; #BWP-Id
|
||||
defaultDownlinkBWP-Id = 1; #BWP-Id
|
||||
|
||||
# bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30,
|
||||
# ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500,
|
||||
# ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8,
|
||||
# spare7, spare6, spare5, spare4, spare3, spare2, spare1 }
|
||||
|
||||
# UplinkConfig
|
||||
# BWP-Uplink
|
||||
# BWP 1 Configuration
|
||||
ul_bwp-Id_1 = 1;
|
||||
ul_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW)
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_bwp1_subcarrierSpacing = 1;
|
||||
|
||||
# BWP 2 Configuration
|
||||
ul_bwp-Id_2 = 2;
|
||||
ul_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW)
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_bwp2_subcarrierSpacing = 1;
|
||||
|
||||
# BWP 3 Configuration
|
||||
ul_bwp-Id_3 = 3;
|
||||
ul_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW)
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_bwp3_subcarrierSpacing = 1;
|
||||
|
||||
firstActiveUplinkBWP-Id = 1; #BWP-Id
|
||||
}
|
||||
);
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "192.168.71.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/24";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/24";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
#pusch_TargetSNRx10 = 150;
|
||||
#pucch_TargetSNRx10 = 200;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
dl_max_mcs = 16; # there are retransmissions if more
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 120;
|
||||
#pucch0_dtx_threshold = 120;
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "yes"
|
||||
nb_tx = 2
|
||||
nb_rx = 2
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
#clock_src = "internal";
|
||||
sdr_addrs = "mgmt_addr=192.168.10.2,addr=192.168.10.2,clock_source=internal,time_source=internal"
|
||||
}
|
||||
);
|
||||
|
||||
THREAD_STRUCT = (
|
||||
{
|
||||
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
parallel_config = "PARALLEL_SINGLE_THREAD";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_ENABLE";
|
||||
}
|
||||
);
|
||||
|
||||
rfsimulator :
|
||||
{
|
||||
serveraddr = "server";
|
||||
serverport = "4043";
|
||||
options = (); #("saviq"); or/and "chanmod"
|
||||
modelname = "AWGN";
|
||||
IQfile = "/tmp/rfsimulator.iqs";
|
||||
};
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
f1ap_log_level ="debug";
|
||||
};
|
||||
@@ -1,107 +0,0 @@
|
||||
#!/bin/bash
|
||||
#/*
|
||||
# * 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
|
||||
# */
|
||||
|
||||
function create_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo " Requirements:"
|
||||
echo " -- uvtool uvtool-libvirt apt-cacher"
|
||||
echo " -- $VM_OSREL image already synced"
|
||||
echo " Default:"
|
||||
echo " -- eNB with USRP"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo " oai-ci-vm-tool create [OPTIONS]"
|
||||
echo ""
|
||||
echo "Mandatory Options:"
|
||||
echo "--------"
|
||||
echo " --job-name #### OR -jn ####"
|
||||
echo " Specify the name of the Jenkins job."
|
||||
echo ""
|
||||
echo " --build-id #### OR -id ####"
|
||||
echo " Specify the build ID of the Jenkins job."
|
||||
echo ""
|
||||
variant_usage
|
||||
echo " Specify the variant to build."
|
||||
echo ""
|
||||
echo " --help OR -h"
|
||||
echo " Print this help message."
|
||||
echo ""
|
||||
}
|
||||
|
||||
function acquire_vm_create_lock {
|
||||
local FlockFile="/tmp/vmclone.lck"
|
||||
local unlocked="0"
|
||||
touch ${FlockFile} 2>/dev/null
|
||||
if [[ $? -ne 0 ]]
|
||||
then
|
||||
echo "Cannot access lock file ${FlockFile}"
|
||||
exit 2
|
||||
fi
|
||||
while [ $unlocked -eq 0 ]
|
||||
do
|
||||
exec 5>${FlockFile}
|
||||
flock -nx 5
|
||||
if [[ $? -ne 0 ]]
|
||||
then
|
||||
echo "Another instance of VM creation is running"
|
||||
sleep 10
|
||||
else
|
||||
unlocked="1"
|
||||
fi
|
||||
done
|
||||
chmod 666 ${FlockFile} 2>/dev/null
|
||||
}
|
||||
|
||||
function release_vm_create_lock {
|
||||
local FlockFile="/tmp/vmclone.lck"
|
||||
rm -Rf ${FlockFile}
|
||||
}
|
||||
|
||||
function create_vm {
|
||||
echo "############################################################"
|
||||
echo "OAI CI VM script"
|
||||
echo "############################################################"
|
||||
echo "VM_NAME = $VM_NAME"
|
||||
echo "VM_MEMORY = $VM_MEMORY MBytes"
|
||||
echo "VM_CPU = $VM_CPU"
|
||||
echo "VM_DISK = $VM_DISK GBytes"
|
||||
|
||||
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]] || [[ "$VM_NAME" == *"-rf-sim"* ]] || [[ "$VM_NAME" == *"-ethernet"* ]] || [[ "$VM_NAME" == *"rf5g-sim"* ]]
|
||||
then
|
||||
echo "This VM type is no longer supported in the pipeline framework"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "############################################################"
|
||||
echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base"
|
||||
echo "############################################################"
|
||||
acquire_vm_create_lock
|
||||
uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml
|
||||
echo "Waiting for VM to be started"
|
||||
uvt-kvm wait $VM_NAME --insecure
|
||||
|
||||
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
|
||||
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
|
||||
release_vm_create_lock
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Dev documentation</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
VM-based RF-Less Environment:
|
||||
|
||||
* [How to setup your test env](./vm_based_simulator_env.md)
|
||||
* [How to deal with OAI source files](./vm_based_simulator_sources.md)
|
||||
* [The main script](./vm_based_simulator_main_scripts.md)
|
||||
* [How to create one or several VM instances](./vm_based_simulator_create.md)
|
||||
* [How to build an OAI variant](./vm_based_simulator_build.md)
|
||||
* [How the build is checked](./vm_based_simulator_check_build.md)
|
||||
* [How to test an OAI variant](./vm_based_simulator_test.md)
|
||||
* [How to destroy all VM instances](./vm_based_simulator_destroy.md)
|
||||
|
||||
Currently missing documentation:
|
||||
* How to generate a build report
|
||||
* How to generate a test report
|
||||
|
||||
---
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Test Environment: build an OAI variant</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ls *.zip
|
||||
localZip.zip
|
||||
$ ./ci-scripts/oai-ci-vm-tool build --help
|
||||
OAI CI VM script
|
||||
Original Author: Raphael Defosseux
|
||||
Requirements:
|
||||
-- uvtool uvtool-libvirt apt-cacher
|
||||
-- xenial image already synced
|
||||
Default:
|
||||
-- eNB with USRP
|
||||
|
||||
Usage:
|
||||
------
|
||||
oai-ci-vm-tool build [OPTIONS]
|
||||
|
||||
Mandatory Options:
|
||||
--------
|
||||
--job-name #### OR -jn ####
|
||||
Specify the name of the Jenkins job.
|
||||
|
||||
--build-id #### OR -id ####
|
||||
Specify the build ID of the Jenkins job.
|
||||
|
||||
--workspace #### OR -ws ####
|
||||
Specify the workspace.
|
||||
|
||||
Options:
|
||||
--------
|
||||
# OpenAirInterface Build Variants
|
||||
--variant enb-usrp OR -v1 ( build and test )
|
||||
--variant phy-sim OR -v3 ( build and test )
|
||||
--variant cppcheck OR -v4 ( build and test )
|
||||
--variant gnb-usrp OR -v5 ( build and test )
|
||||
--variant nr-ue-usrp OR -v6 ( build and test )
|
||||
--variant enb-ethernet OR -v7 ( build and test )
|
||||
--variant ue-ethernet OR -v8 ( build and test )
|
||||
# non-OSA Build Variants
|
||||
--variant flexran-rtc OR -v10 ( build and test non-OSA )
|
||||
# OpenAirInterface Test Variants
|
||||
--variant l1-sim OR -v20 ( test )
|
||||
--variant rf-sim OR -v21 ( test )
|
||||
--variant l2-sim OR -v22 ( test )
|
||||
Specify the variant to build.
|
||||
|
||||
--keep-vm-alive OR -k
|
||||
Keep the VM alive after the build.
|
||||
|
||||
--daemon OR -D
|
||||
Run as daemon
|
||||
|
||||
--help OR -h
|
||||
Print this help message.
|
||||
```
|
||||
|
||||
# 2. Detailed Description #
|
||||
|
||||
Source file concerned: `ci-scripts/buildOnVM.sh`
|
||||
|
||||
## 2.1. build_on_vm function ##
|
||||
|
||||
* First check if the ZIP file is available and if the apt-cacher proxy configuration file is present. If not, it will stop.
|
||||
* Check if the VM instance is alive. If not, create it.
|
||||
* Once the VM is alive, retrieve the IP address with VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
|
||||
* We copy the ZIP file to the VM : `scp localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu`
|
||||
* apt-cacher proxy file: `scp etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu`
|
||||
|
||||
Then we open a SSH session on the VM : `ssh ubuntu@$VM_IP_ADDR`
|
||||
|
||||
* We copy the apt-cacher proxy file to its destination space: `sudo cp 01proxy /etc/apt/apt.conf.d/`
|
||||
* We create an hush login file to eliminate the ssh opening session messages.
|
||||
* We unzip the ZIP file into `/home/ubuntu/tmp/` folder
|
||||
* and we work from there.
|
||||
|
||||
# 3. Typical Usage #
|
||||
|
||||
## 3.1. Build in the foreground, check the results and destroy the VM at the end ##
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ls *.zip
|
||||
localZip.zip
|
||||
$ ./ci-scripts/oai-ci-vm-tool build --workspace /tmp/CI-raphael --job-name RAN-CI-develop --build-id 47 --variant enb-usrp
|
||||
############################################################
|
||||
OAI CI VM script
|
||||
############################################################
|
||||
VM_NAME = RAN-CI-develop-b47-enb-usrp
|
||||
VM_CMD_FILE = RAN-CI-develop-b47-enb-usrp_cmds.txt
|
||||
JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop
|
||||
ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/enb_usrp
|
||||
BUILD_OPTIONS = --eNB -w USRP --mu
|
||||
VM_MEMORY = 2048 MBytes
|
||||
VM_CPU = 4
|
||||
############################################################
|
||||
Creating VM (RAN-CI-develop-b47-enb-usrp) on Ubuntu Cloud Image base
|
||||
############################################################
|
||||
Waiting for VM to be started
|
||||
Warning: Permanently added '192.168.122.2' (ECDSA) to the list of known hosts.
|
||||
RAN-CI-develop-b47-enb-usrp has for IP addr = 192.168.122.2
|
||||
############################################################
|
||||
Copying GIT repo into VM (RAN-CI-develop-b47-enb-usrp)
|
||||
############################################################
|
||||
Warning: Permanently added '192.168.122.2' (ECDSA) to the list of known hosts.
|
||||
############################################################
|
||||
Running install and build script on VM (RAN-CI-develop-b47-enb-usrp)
|
||||
############################################################
|
||||
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-145-generic x86_64)
|
||||
|
||||
* Documentation: https://help.ubuntu.com
|
||||
* Management: https://landscape.canonical.com
|
||||
* Support: https://ubuntu.com/advantage
|
||||
|
||||
Get cloud support with Ubuntu Advantage Cloud Guest:
|
||||
http://www.ubuntu.com/business/services/cloud
|
||||
|
||||
0 packages can be updated.
|
||||
0 updates are security updates.
|
||||
|
||||
New release '18.04.2 LTS' available.
|
||||
Run 'do-release-upgrade' to upgrade to it.
|
||||
|
||||
|
||||
sudo apt-get --yes --quiet install zip subversion libboost-dev
|
||||
unzip -qq -DD ../localZip.zip
|
||||
cd /home/ubuntu/tmp
|
||||
source oaienv
|
||||
cd cmake_targets
|
||||
./build_oai -I --eNB -w USRP --mu
|
||||
|
||||
# Here wait for a few minutes 8 to 12 minutes #
|
||||
|
||||
############################################################
|
||||
Creating a tmp folder to store results and artifacts
|
||||
############################################################
|
||||
############################################################
|
||||
Destroying VM
|
||||
############################################################
|
||||
# Host 192.168.122.2 found: line 19
|
||||
/home/eurecom/.ssh/known_hosts updated.
|
||||
Original contents retained as /home/eurecom/.ssh/known_hosts.old
|
||||
############################################################
|
||||
Checking build status
|
||||
############################################################
|
||||
STATUS seems OK
|
||||
```
|
||||
|
||||
If you are adding the `-k` or `--keep-vm-alive` option, the VM instance will not be destroyed and you explore what happenned.
|
||||
|
||||
## 3.2. Build in the background ##
|
||||
|
||||
This is how it is done in the CI master job pipeline.
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ls *.zip
|
||||
localZip.zip
|
||||
$ ./ci-scripts/oai-ci-vm-tool build --workspace /tmp/CI-raphael --job-name RAN-CI-develop --build-id 47 --variant phy-sim --daemon
|
||||
12:44:24 ############################################################
|
||||
12:44:24 OAI CI VM script
|
||||
12:44:24 ############################################################
|
||||
12:44:24 VM_NAME = RAN-CI-develop-b47-phy-sim
|
||||
12:44:24 VM_CMD_FILE = RAN-CI-develop-b47-phy-sim_cmds.txt
|
||||
12:44:24 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop
|
||||
12:44:24 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim
|
||||
12:44:24 BUILD_OPTIONS = --phy_simulators
|
||||
12:44:24 VM_MEMORY = 2048 MBytes
|
||||
12:44:24 VM_CPU = 4
|
||||
12:44:24 ############################################################
|
||||
12:44:24 Creating VM (RAN-CI-develop-b47-phy-sim) on Ubuntu Cloud Image base
|
||||
12:44:24 ############################################################
|
||||
12:44:27 Waiting for VM to be started
|
||||
12:46:34 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts.
|
||||
12:46:34 RAN-CI-develop-b47-phy-sim has for IP addr = 192.168.122.220
|
||||
12:46:34 ############################################################
|
||||
12:46:34 Copying GIT repo into VM (RAN-CI-develop-b47-phy-sim)
|
||||
12:46:34 ############################################################
|
||||
12:46:34 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts.
|
||||
12:46:34 ############################################################
|
||||
12:46:34 Running install and build script on VM (RAN-CI-develop-b47-phy-sim)
|
||||
12:46:34 ############################################################
|
||||
12:46:34 Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-145-generic x86_64)
|
||||
12:46:34
|
||||
12:46:34 * Documentation: https://help.ubuntu.com
|
||||
12:46:34 * Management: https://landscape.canonical.com
|
||||
12:46:34 * Support: https://ubuntu.com/advantage
|
||||
12:46:34
|
||||
12:46:34 Get cloud support with Ubuntu Advantage Cloud Guest:
|
||||
12:46:34 http://www.ubuntu.com/business/services/cloud
|
||||
12:46:34
|
||||
12:46:34 0 packages can be updated.
|
||||
12:46:34 0 updates are security updates.
|
||||
12:46:34
|
||||
12:46:34 New release '18.04.2 LTS' available.
|
||||
12:46:34 Run 'do-release-upgrade' to upgrade to it.
|
||||
12:46:34
|
||||
12:46:34
|
||||
12:46:34 sudo apt-get --yes --quiet install zip daemon subversion libboost-dev
|
||||
12:46:46 unzip -qq -DD ../localZip.zip
|
||||
12:46:48 source oaienv
|
||||
12:46:48 sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh
|
||||
12:46:48 STATUS seems OK
|
||||
```
|
||||
|
||||
So here is 2.5 minutes, a VM was created, source files copied and the build process is started in the background.
|
||||
|
||||
```bash
|
||||
$ cd /tmp/raphael
|
||||
$ ./ci-scripts/oai-ci-vm-tool wait --workspace /var/jenkins/workspace/RAN-CI-develop --variant phy-sim --job-name RAN-CI-develop --build-id 47 --keep-vm-alive
|
||||
12:49:14 ############################################################
|
||||
12:49:14 OAI CI VM script
|
||||
12:49:14 ############################################################
|
||||
12:49:14 VM_NAME = RAN-CI-develop-b47-phy-sim
|
||||
12:49:14 VM_CMD_FILE = RAN-CI-develop-b47-phy-sim_cmds.txt
|
||||
12:49:14 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop
|
||||
12:49:14 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim
|
||||
12:49:14 BUILD_OPTIONS = --phy_simulators
|
||||
12:49:15 Waiting for VM to be started
|
||||
12:49:15 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts.
|
||||
12:49:16 RAN-CI-develop-b47-phy-sim has for IP addr = 192.168.122.220
|
||||
12:49:16 ############################################################
|
||||
12:49:16 Waiting build process to end on VM (RAN-CI-develop-b47-phy-sim)
|
||||
12:49:16 ############################################################
|
||||
12:49:16 ps -aux | grep build
|
||||
12:54:23 ############################################################
|
||||
12:54:23 Creating a tmp folder to store results and artifacts
|
||||
12:54:23 ############################################################
|
||||
12:54:23 ############################################################
|
||||
12:54:23 Checking build status
|
||||
12:54:23 ############################################################
|
||||
12:54:23 STATUS seems OK
|
||||
```
|
||||
|
||||
Here the `--keep-vm-alive` option is used to keep the VM alive and performs some testing.
|
||||
|
||||
---
|
||||
|
||||
Next step: [how the build is checked](./vm_based_simulator_check_build.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Test Environment: checking the build result</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
Function is called:
|
||||
|
||||
- when building in foreground
|
||||
- when waiting for the background build process is finished
|
||||
|
||||
# 2. Detailed Description #
|
||||
|
||||
Source file concerned: `ci-scripts/waitBuildOnVM.sh`
|
||||
|
||||
## 2.1. check_on_vm_build function ##
|
||||
|
||||
* Retrieve the build log files from the VM instance `ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.txt`
|
||||
* and copy them locally in the workspace at $ARCHIVES_LOC
|
||||
* List all log files that match the pattern. Each should have
|
||||
* the `Built target` pattern (the library/executable SHALL link)
|
||||
* Evaluate the remaining space on VM disk
|
||||
* The number of patterned log files SHALL match $NB_PATTERN_FILES defined in `ci-scripts/oai-ci-vm-tool` script for the variant
|
||||
|
||||
---
|
||||
|
||||
Next step: [how to test a function](./vm_based_simulator_test.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Test Environment: create a VM instance</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ./ci-scripts/oai-ci-vm-tool create --help
|
||||
OAI CI VM script
|
||||
Original Author: Raphael Defosseux
|
||||
Requirements:
|
||||
-- uvtool uvtool-libvirt apt-cacher
|
||||
-- xenial image already synced
|
||||
Default:
|
||||
-- eNB with USRP
|
||||
|
||||
Usage:
|
||||
------
|
||||
oai-ci-vm-tool create [OPTIONS]
|
||||
|
||||
Mandatory Options:
|
||||
--------
|
||||
--job-name #### OR -jn ####
|
||||
Specify the name of the Jenkins job.
|
||||
|
||||
--build-id #### OR -id ####
|
||||
Specify the build ID of the Jenkins job.
|
||||
|
||||
# OpenAirInterface Build Variants
|
||||
--variant enb-usrp OR -v1 ( build and test )
|
||||
--variant phy-sim OR -v3 ( build and test )
|
||||
--variant cppcheck OR -v4 ( build and test )
|
||||
--variant gnb-usrp OR -v5 ( build and test )
|
||||
--variant nr-ue-usrp OR -v6 ( build and test )
|
||||
--variant enb-ethernet OR -v7 ( build and test )
|
||||
--variant ue-ethernet OR -v8 ( build and test )
|
||||
# non-OSA Build Variants
|
||||
--variant flexran-rtc OR -v10 ( build and test non-OSA )
|
||||
# OpenAirInterface Test Variants
|
||||
--variant l1-sim OR -v20 ( test )
|
||||
--variant rf-sim OR -v21 ( test )
|
||||
--variant l2-sim OR -v22 ( test )
|
||||
Specify the variant to build.
|
||||
|
||||
--help OR -h
|
||||
Print this help message.
|
||||
```
|
||||
|
||||
# 2. Detailed Description #
|
||||
|
||||
Source file concerned: `ci-scripts/createVM.sh`
|
||||
|
||||
## 2.1. create_vm function ##
|
||||
|
||||
This is the function that is being called from the main oai-vm-tool script.
|
||||
|
||||
The main purpose is to start a VM instance:
|
||||
|
||||
```bash
|
||||
uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml
|
||||
```
|
||||
|
||||
Variables are set in the main script based on the options.
|
||||
|
||||
`--unsafe-caching` option is used because our VM instances are throw-away's.
|
||||
|
||||
`--template ci-scripts/template-host.xml` is used to duplicate the CPU properties to the VM instance. **VERY IMPORTANT to build OAI**
|
||||
|
||||
## 2.2. Lock / Unlock functions ##
|
||||
|
||||
There are `acquire_vm_create_lock` and `release_vm_create_lock` functions.
|
||||
|
||||
Creating Virtual Machines instances in parallel **creates a lot of stress** on the host server HW. If you launch creations in parallel (Jenkins pipeline could do it) or you are several people working on the same host server, this mechanism atomizes the creation process and wait until the previous VM creation is finished.
|
||||
|
||||
# 3. Typical Usage #
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ./ci-scripts/oai-ci-vm-tool create --job-name raphael --build-id 1 --variant phy-sim
|
||||
# or a more **unique approach**
|
||||
$ ./ci-scripts/oai-ci-vm-tool create -jn toto -id 1 -v2
|
||||
```
|
||||
|
||||
The Jenkins pipeline uses the master job name as `job-name` option and the job-build ID.
|
||||
|
||||
Try to be unique if you are several developers working on the same host server.
|
||||
|
||||
Finally, typically I never use the `create` command. I use directly the build command that checks if VM is created and if not, will create it. See next step.
|
||||
|
||||
---
|
||||
|
||||
Next step: [how to build an OAI variant](./vm_based_simulator_build.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Test Environment: Properly Destroy all VM instances</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ./ci-scripts/oai-ci-vm-tool destroy --help
|
||||
OAI CI VM script
|
||||
Original Author: Raphael Defosseux
|
||||
Requirements:
|
||||
-- uvtool uvtool-libvirt apt-cacher
|
||||
|
||||
Usage:
|
||||
------
|
||||
oai-ci-vm-tool destroy [OPTIONS]
|
||||
|
||||
Mandatory Options:
|
||||
--------
|
||||
--job-name #### OR -jn ####
|
||||
Specify the name of the Jenkins job.
|
||||
|
||||
--build-id #### OR -id ####
|
||||
Specify the build ID of the Jenkins job.
|
||||
|
||||
Options:
|
||||
--------
|
||||
--help OR -h
|
||||
Print this help message.
|
||||
```
|
||||
|
||||
# 2. Detailed Description #
|
||||
|
||||
Source file concerned: `ci-scripts/destroyAllRunningVM.sh`
|
||||
|
||||
## 2.1. destroy_vm function ##
|
||||
|
||||
This is the function that is being called from the main oai-vm-tool script.
|
||||
|
||||
The main purpose is to destroy all VM instances whose name matches a pattern.
|
||||
|
||||
It also cleans up the `.ssh/known_hosts` file.
|
||||
|
||||
# 3. Typical Usage #
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ./ci-scripts/oai-ci-vm-tool destroy --job-name raphael --build-id 1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
You can go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Simulator Test Environment</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
This document explains how the master pipeline works and how any developer could contribute to add testing.
|
||||
|
||||
It is an extension to the wiki [page](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/ci/enb-master-job).
|
||||
|
||||
The purpose of this master pipeline is to:
|
||||
|
||||
* Validate that a Merge Request is mergeable
|
||||
* Validate that a Merge Request is following coding guidelines
|
||||
* Validate that a Merge Request is not breaking any typical build variant
|
||||
* Validate that a Merge Request is not breaking any legacy simulator-based test
|
||||
|
||||
We will mainly focused on the 2 last items.
|
||||
|
||||
Last point, this documentation is valid for all CI-supported branches:
|
||||
|
||||
* `master`
|
||||
* `develop`
|
||||
|
||||
But the feature set may not be aligned. **The principles still apply.**
|
||||
|
||||
# 2. Prerequisites #
|
||||
|
||||
Some details are available on this wiki [section](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/ci/enb-ci-architecture#22-pipeline-executor).
|
||||
|
||||
Currently we have a host server (`bellatrix`) with the current parameters:
|
||||
|
||||
* 40 x Intel(R) Xeon(R) CPU E5-2640 v4 @ 2.40GHz
|
||||
* 64 Gbytes RAM
|
||||
* Ubuntu 16.04.3 LTS (xenial)
|
||||
|
||||
For you to replicate this environment, you need a strong server:
|
||||
|
||||
* At least 16 cores
|
||||
* Ubuntu 16 (xenial) or higher (such as bionic, not tested)
|
||||
|
||||
Also we are using a Virtual Machine (VM for the rest of document) based strategy for the moment.
|
||||
|
||||
So you need to install 2 tools:
|
||||
|
||||
* uvt-kvm
|
||||
* apt-cacher
|
||||
|
||||
We are planning to also add:
|
||||
|
||||
* A Red Hat Linux Entreprise 7.6 host environment
|
||||
* A Container-based strategy (such as Docket and Kubernetes)
|
||||
|
||||
## 2.1. uvtool installation ##
|
||||
|
||||
```bash
|
||||
$ sudo apt-get install uvtool
|
||||
# if you don't have already, create an ssh key
|
||||
$ ssh-keygen -b 2048
|
||||
# retrieve an image
|
||||
$ sudo uvt-simplestreams-libvirt sync arch=amd64 release=xenial
|
||||
# we might soon switch to an Ubuntu 18.04 version
|
||||
$ sudo uvt-simplestreams-libvirt sync arch=amd64 release=bionic
|
||||
$ uvt-simplestreams-libvirt query
|
||||
release=bionic arch=amd64 label=release (20190402)
|
||||
release=xenial arch=amd64 label=release (20190406)
|
||||
```
|
||||
|
||||
On our server, I don't update (sync) that often (every 2-4 months).
|
||||
|
||||
For more details:
|
||||
|
||||
* uvtool syntax is [here](http://manpages.ubuntu.com/manpages/trusty/man1/uvt-kvm.1.html)
|
||||
* more readable tutorial is [here](https://help.ubuntu.com/lts/serverguide/cloud-images-and-uvtool.html)
|
||||
|
||||
## 2.2. apt-cacher-server installation ##
|
||||
|
||||
I recommend to follow to the letter this [tutorial](https://help.ubuntu.com/community/Apt-Cacher-Server).
|
||||
|
||||
The reason: we are creating/using/destroying a lot of VM instances and we are always installing the same packages.
|
||||
This service allows to cache on the host and, doing so, **decreases the pressure on your internet bandwith usage**.
|
||||
It also optimizes time at build stage.
|
||||
|
||||
```bash
|
||||
$ sudo apt-get install apt-cacher apache2
|
||||
$ sudo vi /etc/default/apt-cache
|
||||
$ sudo service apache2 restart
|
||||
|
||||
# Server configuration
|
||||
$ sudo vi /etc/apt-cacher/apt-cacher.conf
|
||||
--> allowed_hosts = *
|
||||
--> fix the installer_files_regexp
|
||||
$ sudo vi /etc/apt/apt.conf.d/01proxy
|
||||
--> add `Acquire::http::Proxy "http://<IP address or hostname of the apt-cacher server>:3142";`
|
||||
$ sudo service apt-cacher restart
|
||||
```
|
||||
|
||||
This last file (/etc/apt/apt.conf.d/01proxy) is very important since it is tested in any CI script.
|
||||
|
||||
---
|
||||
|
||||
We can now switch to the next step: [how to deal with oai sources](./vm_based_simulator_sources.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Test Environment: the Main Script</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
The file name is `./ci-scripts/oai-ci-vm-tool` from the workspace root.
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ./ci-scripts/oai-ci-vm-tool --help
|
||||
OAI CI VM script
|
||||
Original Author: Raphael Defosseux
|
||||
Requirements:
|
||||
-- uvtool uvtool-libvirt apt-cacher
|
||||
-- xenial image already synced
|
||||
|
||||
Usage:
|
||||
------
|
||||
oai-ci-vm-tool (-h|--help) {create,destroy,build,wait,test,report-build,report-test} ...
|
||||
|
||||
```
|
||||
|
||||
This is a **BASH** script.
|
||||
|
||||
|
||||
# 2. Sub BASH scripts #
|
||||
|
||||
The main script is including a bunch of sub BASH scripts.
|
||||
|
||||
* ci-scripts/createVM.sh
|
||||
* ci-scripts/buildOnVM.sh
|
||||
* ci-scripts/waitBuildOnVM.sh
|
||||
* ci-scripts/destroyAllRunningVM.sh
|
||||
* ci-scripts/runTestOnVM.sh
|
||||
* ci-scripts/reportBuildLocally.sh
|
||||
* ci-scripts/reportTestLocally.sh
|
||||
|
||||
**NOTE: ci-scripts/runTestOnVM.sh is getting big and will certainly be split to facilitate maintenance. Start functions will be also factorized.**
|
||||
|
||||
# 3. Main script features #
|
||||
|
||||
The main purpose of the main script is decipher the options and launch the requested function.
|
||||
|
||||
It is also **testing if uvtool and apt-cacher are installed.**
|
||||
|
||||
It finally provides parameters to the requested functions. Parameter definition is centralized there.
|
||||
|
||||
For example:
|
||||
|
||||
for VM instance creation:
|
||||
|
||||
* the instance name: VM_NAME
|
||||
* the RAM and number of CPUs: VM_MEMORY, VM_CPU
|
||||
|
||||
for OAI variant build:
|
||||
|
||||
* build options: BUILD_OPTIONS
|
||||
* build log file to parse: LOG_PATTERN
|
||||
* the number of log files to parse: NB_PATTERN_FILES
|
||||
|
||||
You can get the list of variant specific variables specifying the variant argument when asking for help:
|
||||
|
||||
``` bash
|
||||
./ci-scripts/oai-ci-vm-tool help variant
|
||||
--variant flexran-rtc OR -v10 ( build and test non-OSA )
|
||||
VM_NAME=ci-flexran-rtc ARCHIVES_LOC=flexran
|
||||
VM_MEMORY=2048 VM_CPU=4
|
||||
NB_PATTERN_FILES=1 BUILD_OPTIONS="cmake . && make -j2"
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant enb-usrp OR -v1 ( build and test )
|
||||
VM_NAME=ci-enb-usrp ARCHIVES_LOC=enb_usrp
|
||||
VM_MEMORY=2048 VM_CPU=4
|
||||
NB_PATTERN_FILES=9 BUILD_OPTIONS="--eNB -w USRP --mu"
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant l1-sim OR -v20 ( test )
|
||||
VM_NAME=ci-l1-sim ARCHIVES_LOC=l1_sim
|
||||
VM_MEMORY=2048 VM_CPU=4
|
||||
NB_PATTERN_FILES=9 BUILD_OPTIONS=""
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant rf-sim OR -v21 ( test )
|
||||
VM_NAME=ci-rf-sim ARCHIVES_LOC=rf_sim
|
||||
VM_MEMORY=2048 VM_CPU=4
|
||||
NB_PATTERN_FILES=9 BUILD_OPTIONS=""
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant l2-sim OR -v22 ( test )
|
||||
VM_NAME=ci-l2-sim ARCHIVES_LOC=l2_sim
|
||||
VM_MEMORY=2048 VM_CPU=4
|
||||
NB_PATTERN_FILES=9 BUILD_OPTIONS=""
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant phy-sim OR -v3 ( build and test )
|
||||
VM_NAME=ci-phy-sim ARCHIVES_LOC=phy_sim
|
||||
VM_MEMORY=2048 VM_CPU=4
|
||||
NB_PATTERN_FILES=3 BUILD_OPTIONS="--phy_simulators"
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant cppcheck OR -v4 ( build and test )
|
||||
VM_NAME=ci-cppcheck ARCHIVES_LOC=cppcheck
|
||||
VM_MEMORY=4096 VM_CPU=4
|
||||
NB_PATTERN_FILES=1 BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -j4"
|
||||
LOG_PATTERN=cppcheck.xml
|
||||
|
||||
--variant enb-ethernet OR -v7 ( build and test )
|
||||
VM_NAME=ci-enb-ethernet ARCHIVES_LOC=enb_eth
|
||||
VM_MEMORY=4096 VM_CPU=4
|
||||
NB_PATTERN_FILES=8 BUILD_OPTIONS="--eNB"
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant ue-ethernet OR -v8 ( build and test )
|
||||
VM_NAME=ci-ue-ethernet ARCHIVES_LOC=ue_eth
|
||||
VM_MEMORY=4096 VM_CPU=4
|
||||
NB_PATTERN_FILES=12 BUILD_OPTIONS="--UE"
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
```
|
||||
|
||||
To define a new variant you just need to define a function which name conforms to `function variant__v<n>__<variant_name>` where n and variant_name will respectively define the short and long options for your variant. The function only needs to define the variant dependent variables. For many variables, default values are set in the `check_set_variant` function. When a variant doesn't define the BUILD_OPTIONS variable it cannot be used for the `build` `wait` and `create` commands.
|
||||
|
||||
The main scripts also allows the definition of non variant-dependant variable via the `--setvar_<variable name> <variable value>` options.
|
||||
You can get the list of these variables by using `help setvar`:
|
||||
|
||||
```BASH
|
||||
./ci-scripts/oai-ci-vm-tool help setvar
|
||||
--setvar_<varname> <value> where varname is one of:
|
||||
VM_OSREL : OS release to use in virtual machines
|
||||
RUN_EXPERIMENTAL : Enforce execution of variants with EXPERIMENTAL variable set to "true"
|
||||
```
|
||||
|
||||
To add a new non-variant dependant variable you need:
|
||||
* Add an item to the `AUTHORIZED_VAR` array
|
||||
* In the `setvar_usage`function, add your help string in the HELP_VAR["<your variable name>"] variable.
|
||||
* Write the bash code for your variable.
|
||||
|
||||
Example of non variant dependent usage:
|
||||
|
||||
``` bash
|
||||
./ci-scripts/oai-ci-vm-tool test -v21 -ws /usr/local/oai/enhance_CI_extEPC/openairinterface5g -id 1 -jn testci
|
||||
Currently testci-b1-rf-sim Testing is not implemented / enabled
|
||||
Comment out these lines in ./ci-scripts/oai-ci-vm-tool if you want to run it
|
||||
or use option --setvar_RUN_EXPERIMENTAL=true to test it
|
||||
|
||||
|
||||
./ci-scripts/oai-ci-vm-tool test -v21 -ws /usr/local/oai/enhance_CI_extEPC/openairinterface5g -id 1 -jn testci --setvar_RUN_EXPERIMENTAL true
|
||||
Setting RUN_EXPERIMENTAL to true...
|
||||
############################################################
|
||||
OAI CI VM script
|
||||
############################################################
|
||||
ENB_VM_NAME = testci-b1-enb-ethernet
|
||||
ENB_VM_CMD_FILE = testci-b1-enb-ethernet_cmds.txt
|
||||
UE_VM_NAME = testci-b1-ue-ethernet
|
||||
UE_VM_CMD_FILE = testci-b1-ue-ethernet_cmds.txt
|
||||
JENKINS_WKSP = /usr/local/oai/enhance_CI_extEPC/openairinterface5g
|
||||
ARCHIVES_LOC = /usr/local/oai/enhance_CI_extEPC/openairinterface5g/archives/rf_sim/test
|
||||
############################################################
|
||||
Waiting for ENB VM to be started
|
||||
...........................
|
||||
```
|
||||
|
||||
In the same way, you can set the variable `VM_OSREL` to run the test in virtual machines of the specified OS release:
|
||||
|
||||
``` bash
|
||||
./ci-scripts/oai-ci-vm-tool test -v21 -ws /usr/local/oai/enhance_CI_extEPC/openairinterface5g -id 1 -jn testci --setvar_VM_OSREL bionic
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Next step: [how to create one or several VM instances](./vm_based_simulator_create.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
@@ -1,83 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Simulator OAI source management</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
The idea of this section is to optimize/uniform source management for several VM instances.
|
||||
|
||||
If we were cloning the same repository in each VM we are creating, we would put so much pressure on the central GitLab repository.
|
||||
|
||||
The solution:
|
||||
|
||||
* clone/fetch on a given clean workspace and tar/zip only the source files without any artifacts.
|
||||
* we then copy the tar/zip file to each VM instance
|
||||
* and within each VM instance, unzip
|
||||
|
||||
# 2. Centralized Workspace #
|
||||
|
||||
You can create a brand new workspace by cloning:
|
||||
|
||||
```bash
|
||||
$ mkdir /tmp/CI-raphael
|
||||
$ cd /tmp/CI-raphael
|
||||
$ git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git .
|
||||
$ git checkout develop
|
||||
```
|
||||
|
||||
You can also use your current cloned workspace and any `develop`-based branch.
|
||||
|
||||
```bash
|
||||
$ cd /home/raphael/openairinterface5g
|
||||
$ git fetch
|
||||
$ git checkout develop-improved-documentation
|
||||
# CAUTION: the following command will remove any file that has not already been added to GIT
|
||||
$ sudo git clean -x -d -ff
|
||||
$ git status
|
||||
On branch develop-improved-documentation
|
||||
Your branch is up-to-date with 'origin/develop-improved-documentation'.
|
||||
nothing to commit, working directory clean
|
||||
```
|
||||
|
||||
You can also have modified files.
|
||||
|
||||
**The main point is to have NO ARTIFACTS from a previous build in your workspace.**
|
||||
|
||||
Last point, the workspace folder name is not necesseraly `openairinterface5g`. But all the following commands will be run for the root of the workspace.
|
||||
|
||||
For clarity, I will always use `/tmp/CI-raphael` as $WORKSPACE.
|
||||
|
||||
# 3. Create the ZIP file #
|
||||
|
||||
```bash
|
||||
# go to root of workspace
|
||||
$ cd /tmp/CI-raphael
|
||||
$ zip -r -qq localZip.zip .
|
||||
```
|
||||
|
||||
The **Jenkins Pipeline** performs automatically these operations.
|
||||
|
||||
In addition, in case of a merge request, it tries to merge with the target branch and might create a dummy local commit.
|
||||
|
||||
See [section](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/ci/enb-master-job#32-verify-guidelines-stage)
|
||||
|
||||
---
|
||||
|
||||
Next step: [the main scripts](./vm_based_simulator_main_scripts.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Test Environment: Testing an OAI variant</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
Currently 1 build variant can be directly tested:
|
||||
|
||||
* Physical Simulators
|
||||
|
||||
In addition, 2 build variants are used:
|
||||
|
||||
* OAI eNB with ETHERNET transport
|
||||
* OAI UE with ETHERNET transport
|
||||
|
||||
for the following scenarios:
|
||||
|
||||
* L1 simulator w/ a channel simulator (NOT IMPLEMENTED)
|
||||
* RF simulator : (IMPLEMENTED but not working as of 2019.w15)
|
||||
* L2 nFAPI simulator
|
||||
|
||||
Tests are run sequentially in the Jenkins pipeline because:
|
||||
|
||||
* We want to mutualize the VM creation for an EPC
|
||||
* We have seen performance issues when running in parallel.
|
||||
|
||||
|
||||
```bash
|
||||
./ci-scripts/oai-ci-vm-tool test --help
|
||||
OAI CI VM script
|
||||
Original Author: Raphael Defosseux
|
||||
Requirements:
|
||||
-- uvtool uvtool-libvirt apt-cacher
|
||||
-- xenial image already synced
|
||||
Default:
|
||||
-- eNB with USRP
|
||||
|
||||
Usage:
|
||||
------
|
||||
oai-ci-vm-tool test [OPTIONS]
|
||||
|
||||
Options:
|
||||
--------
|
||||
--job-name #### OR -jn ####
|
||||
Specify the name of the Jenkins job.
|
||||
|
||||
--build-id #### OR -id ####
|
||||
Specify the build ID of the Jenkins job.
|
||||
|
||||
--workspace #### OR -ws ####
|
||||
Specify the workspace.
|
||||
|
||||
# OpenAirInterface Build Variants
|
||||
--variant enb-usrp OR -v1 ( build and test )
|
||||
--variant phy-sim OR -v3 ( build and test )
|
||||
--variant cppcheck OR -v4 ( build and test )
|
||||
--variant gnb-usrp OR -v5 ( build and test )
|
||||
--variant nr-ue-usrp OR -v6 ( build and test )
|
||||
--variant enb-ethernet OR -v7 ( build and test )
|
||||
--variant ue-ethernet OR -v8 ( build and test )
|
||||
# non-OSA Build Variants
|
||||
--variant flexran-rtc OR -v10 ( build and test non-OSA )
|
||||
# OpenAirInterface Test Variants
|
||||
--variant l1-sim OR -v20 ( test )
|
||||
--variant rf-sim OR -v21 ( test )
|
||||
--variant l2-sim OR -v22 ( test )
|
||||
Specify the variant to build.
|
||||
|
||||
--keep-vm-alive OR -k
|
||||
Keep the VM alive after the build.
|
||||
|
||||
--help OR -h
|
||||
Print this help message.
|
||||
```
|
||||
|
||||
# 2. Detailed Description #
|
||||
|
||||
Source file concerned: `ci-scripts/run_test_on_vm.sh`
|
||||
|
||||
**TBD when file is re-structured.**
|
||||
|
||||
# 3. Typical Usage #
|
||||
|
||||
## 3.1. Testing the physical simulators ##
|
||||
|
||||
```bash
|
||||
$ ./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant phy-sim --job-name RAN-CI-develop --build-id 47
|
||||
12:54:29 ############################################################
|
||||
12:54:29 OAI CI VM script
|
||||
12:54:29 ############################################################
|
||||
12:54:29 VM_NAME = RAN-CI-develop-b47-phy-sim
|
||||
12:54:29 VM_CMD_FILE = RAN-CI-develop-b47-phy-sim_cmds.txt
|
||||
12:54:29 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop
|
||||
12:54:29 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim/test
|
||||
12:54:29 ############################################################
|
||||
12:54:29 Waiting for VM to be started
|
||||
12:54:29 ############################################################
|
||||
12:54:29 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts.
|
||||
12:54:30 RAN-CI-develop-b47-phy-sim has for IP addr = 192.168.122.220
|
||||
...
|
||||
13:04:48 Test Results are written to /home/ubuntu/tmp/cmake_targets/autotests/log/results_autotests.xml
|
||||
13:05:00 ############################################################
|
||||
13:05:00 Creating a tmp folder to store results and artifacts
|
||||
13:05:00 ############################################################
|
||||
13:05:00 /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim/test /var/jenkins/workspace/RAN-CI-develop
|
||||
13:05:04 /var/jenkins/workspace/RAN-CI-develop
|
||||
13:05:04 ############################################################
|
||||
13:05:04 Destroying VM
|
||||
13:05:04 ############################################################
|
||||
13:05:06 # Host 192.168.122.220 found: line 21
|
||||
13:05:06 /home/eurecom/.ssh/known_hosts updated.
|
||||
13:05:06 Original contents retained as /home/eurecom/.ssh/known_hosts.old
|
||||
13:05:06 ############################################################
|
||||
13:05:06 Checking run status
|
||||
13:05:06 ############################################################
|
||||
13:05:06 NB_FOUND_FILES = 1
|
||||
13:05:06 NB_RUNS = 20
|
||||
13:05:06 NB_FAILURES = 0
|
||||
13:05:06 STATUS seems OK
|
||||
```
|
||||
|
||||
Note that the VM instance is destroyed. You do that when you are sure your test is passing.
|
||||
|
||||
## 3.2. Test the RF simulator ##
|
||||
|
||||
```bash
|
||||
./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant rf-sim --job-name RAN-CI-develop --build-id 48 --keep-vm-alive
|
||||
15:24:45 Currently RF-Simulator Testing is not implemented / enabled
|
||||
15:24:45 Comment out these lines in ./ci-scripts/oai-ci-vm-tool if you want to run it
|
||||
15:24:45 STATUS seems OK
|
||||
```
|
||||
|
||||
## 3.3. Testing the L2-nFAPI simulator
|
||||
|
||||
```bash
|
||||
./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant l2-sim --job-name RAN-CI-develop --build-id 48
|
||||
15:24:47 ############################################################
|
||||
15:24:47 OAI CI VM script
|
||||
15:24:47 ############################################################
|
||||
15:24:47 ENB_VM_NAME = RAN-CI-develop-b48-enb-ethernet
|
||||
15:24:47 ENB_VM_CMD_FILE = RAN-CI-develop-b48-enb-ethernet_cmds.txt
|
||||
15:24:47 UE_VM_NAME = RAN-CI-develop-b48-ue-ethernet
|
||||
15:24:47 UE_VM_CMD_FILE = RAN-CI-develop-b48-ue-ethernet_cmds.txt
|
||||
15:24:47 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop
|
||||
15:24:47 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/l2_sim/test
|
||||
15:24:47 ############################################################
|
||||
15:24:47 Waiting for ENB VM to be started
|
||||
15:24:47 ############################################################
|
||||
15:24:47 Warning: Permanently added '192.168.122.110' (ECDSA) to the list of known hosts.
|
||||
15:24:48 RAN-CI-develop-b48-enb-ethernet has for IP addr = 192.168.122.110
|
||||
15:24:48 ############################################################
|
||||
15:24:48 Waiting for UE VM to be started
|
||||
15:24:48 ############################################################
|
||||
15:24:49 Warning: Permanently added '192.168.122.90' (ECDSA) to the list of known hosts.
|
||||
15:24:50 RAN-CI-develop-b48-ue-ethernet has for IP addr = 192.168.122.90
|
||||
15:24:50 ############################################################
|
||||
15:24:50 Test EPC on VM (RAN-CI-develop-b48-epc) will be using ltebox
|
||||
15:24:50 ############################################################
|
||||
15:24:50 EPC_VM_CMD_FILE = RAN-CI-develop-b48-epc_cmds.txt
|
||||
15:24:50 Waiting for VM to be started
|
||||
15:24:50 Warning: Permanently added '192.168.122.156' (ECDSA) to the list of known hosts.
|
||||
15:24:51 RAN-CI-develop-b48-epc has for IP addr = 192.168.122.156
|
||||
...
|
||||
15:42:44 ############################################################
|
||||
15:42:44 Destroying VMs
|
||||
15:42:44 ############################################################
|
||||
15:42:46 # Host 192.168.122.110 found: line 18
|
||||
15:42:46 /home/eurecom/.ssh/known_hosts updated.
|
||||
15:42:46 Original contents retained as /home/eurecom/.ssh/known_hosts.old
|
||||
15:42:47 # Host 192.168.122.90 found: line 18
|
||||
15:42:47 /home/eurecom/.ssh/known_hosts updated.
|
||||
15:42:47 Original contents retained as /home/eurecom/.ssh/known_hosts.old
|
||||
15:42:47 ############################################################
|
||||
15:42:47 Checking run status
|
||||
15:42:47 ############################################################
|
||||
15:42:47 STATUS failed?
|
||||
```
|
||||
---
|
||||
|
||||
Final step: [how to properly destroy all VM instances](./vm_based_simulator_destroy.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -287,6 +287,8 @@ def GetParametersFromXML(action):
|
||||
#CiTestObj.air_interface = 'ocp-enb'
|
||||
logging.error('OCP UE -- NOT SUPPORTED')
|
||||
|
||||
CiTestObj.cmd_prefix = test.findtext('cmd_prefix') or ""
|
||||
|
||||
elif action == 'Terminate_OAI_UE':
|
||||
UE_instance=test.findtext('UE_instance')
|
||||
if (UE_instance is None):
|
||||
|
||||
@@ -1,889 +0,0 @@
|
||||
#!/bin/bash
|
||||
#/*
|
||||
# * 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
|
||||
# */
|
||||
|
||||
|
||||
function top_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo " Requirements:"
|
||||
echo " -- uvtool uvtool-libvirt apt-cacher"
|
||||
echo " -- $VM_OSREL image already synced"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo " oai-ci-vm-tool (-h|--help) { `for i in "${COMMANDS_NAME[@]}"; do echo -n $i,;done` ..." }
|
||||
echo ""
|
||||
}
|
||||
|
||||
function variant_usage {
|
||||
|
||||
for (( i=0 ; i<${#VARIANTS_LONG[@]} ; i++ ))
|
||||
do
|
||||
unset BUILD_OPTIONS
|
||||
unset VARIANT_INFO
|
||||
check_set_variant "${VARIANTS_SHORT[$i]}"
|
||||
printf " --variant %-15s OR -%-3s" "${VARIANTS_LONG[$i]}" "${VARIANTS_SHORT[$i]}"
|
||||
if [ "$BUILD_OPTIONS" = "" ]
|
||||
then
|
||||
echo -n " ( test "
|
||||
else
|
||||
echo -n " ( build and test "
|
||||
fi
|
||||
echo "$VARIANT_INFO )"
|
||||
if [ "$1" = "full" ]
|
||||
then
|
||||
printf " VM_NAME=%-15s ARCHIVES_LOC=%-15s\n" "$VM_NAME" "$ARCHIVES_LOC"
|
||||
printf " VM_MEMORY=%-15s VM_CPU=%-15s VM_DISK=%-15s\n" "$VM_MEMORY" "$VM_CPU" "$VM_DISK"
|
||||
printf " NB_PATTERN_FILES=%-15s BUILD_OPTIONS=%-15s\n" "$NB_PATTERN_FILES" "\"$BUILD_OPTIONS\""
|
||||
printf " LOG_PATTERN=%-15s EXPERIMENTAL=%-15s\n\n\n" "$LOG_PATTERN" "$EXPERIMENTAL"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function command_options_usage {
|
||||
|
||||
local -A HELP_MSG
|
||||
HELP_MSG["jn"]=" Specify the name of the Jenkins job."
|
||||
HELP_MSG["id"]=" Specify the build ID of the Jenkins job."
|
||||
HELP_MSG["ws"]=" Specify the workspace"
|
||||
HELP_MSG["var"]=" Specify the variant to build."
|
||||
HELP_MSG["k"]=" Keep the VM alive after the build."
|
||||
HELP_MSG["D"]=" Run as daemon"
|
||||
HELP_MSG["gu"]=" Specify the URL of the GIT Repository."
|
||||
HELP_MSG["pu"]=" trigger a push action from the Jenkins job to the specified url, \"--trigger pu\" can also be used"
|
||||
HELP_MSG["mr"]=" trigger a merge request action from the Jenkins job, \"--trigger mr\" can also be used"
|
||||
HELP_MSG["sb"]=" Specify the source branch of the merge request."
|
||||
HELP_MSG["sc"]=" Specify the source commit ID (SHA-1) of the merge request."
|
||||
HELP_MSG["tb"]=" Specify the target branch of the merge request (usually develop)."
|
||||
HELP_MSG["tc"]=" Specify the target commit ID (SHA-1) of the merge request."
|
||||
HELP_MSG["br"]=" Specify the branch of the push event."
|
||||
HELP_MSG["co"]=" Specify the commit ID (SHA-1) of the push event."
|
||||
HELP_MSG["epc"]=" (two arguments) Specify the ip addresses of an external EPC, on respectively the core network and the UEs network"
|
||||
HELP_MSG["sim"]=" Specify the path to the sim file, used to emulate the oai UE sim card "
|
||||
for (( m=0 ; m<2 ; m++ ))
|
||||
do
|
||||
if [[ $m -eq 0 || ( $m > 0 && ${MANDATORY_OPTMASK[$m]} > 0 ) ]]
|
||||
then
|
||||
echo "Mandatory Options ($((m+1))):"
|
||||
echo "---------------------"
|
||||
for (( i=0 ; i<${#SHORT_OPTIONS[@]} ; i++ ))
|
||||
do
|
||||
if [ $(( MANDATORY_OPTMASK[$m] & $(( 2**$i )) )) -ne 0 ]
|
||||
then
|
||||
if [ "${LONG_OPTIONS[$i]}" != "" ]
|
||||
then
|
||||
local ARGPATTERN
|
||||
if [[ !("${HELP_MSG[${SHORT_OPTIONS[$i]}]}" =~ "Specify") ]]
|
||||
then
|
||||
ARGPATTERN=""
|
||||
elif [[ "${HELP_MSG[${SHORT_OPTIONS[$i]}]}" =~ "(two arguments)" ]]
|
||||
then
|
||||
ARGPATTERN="#### ####"
|
||||
else
|
||||
ARGPATTERN="####"
|
||||
fi
|
||||
printf " %s %s OR " "--${LONG_OPTIONS[$i]}" "$ARGPATTERN"
|
||||
fi
|
||||
printf "%s %s \n" "-${SHORT_OPTIONS[$i]}" "$ARGPATTERN"
|
||||
printf " %s\n\n" "${HELP_MSG[${SHORT_OPTIONS[$i]}]}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
echo "Options:"
|
||||
echo "--------"
|
||||
|
||||
for (( i=0 ; i<${#SHORT_OPTIONS[@]} ; i++ ))
|
||||
do
|
||||
if [ $(( ALLOWED_OPTMASK & $(( 2**$i )) )) -ne 0 ]
|
||||
then
|
||||
if [ "${LONG_OPTIONS[$i]}" != "" ]
|
||||
then
|
||||
printf " %s #### OR " "--${LONG_OPTIONS[$i]}"
|
||||
fi
|
||||
printf "%s #### \n" "-${SHORT_OPTIONS[$i]}"
|
||||
printf " %s\n\n" "${HELP_MSG[${SHORT_OPTIONS[$i]}]}"
|
||||
fi
|
||||
done
|
||||
|
||||
for (( i=0 ; i<${#SHORT_OPTIONS[@]} ; i++ ))
|
||||
do
|
||||
if [ $(( ALLOWED_OPTMASK & $(( 2**$i )) )) -ne 0 ]
|
||||
then
|
||||
if [ "$(type -t ${LONG_OPTIONS[$i]}_usage)" = 'function' ]
|
||||
then
|
||||
${LONG_OPTIONS[$i]}_usage
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo " --help OR -h"
|
||||
echo " Print this help message."
|
||||
echo ""
|
||||
}
|
||||
|
||||
# function to set specific behavior depending on the TESTPLATFORM_OWNER variable
|
||||
# which may be set by a jenkins server for exemple
|
||||
function platform_set {
|
||||
if [ "$TESTPLATFORM_OWNER" != "" ]
|
||||
then
|
||||
echo "Running on $TESTPLATFORM_OWNER platform"
|
||||
if [ -x "/usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh" ]
|
||||
then
|
||||
. /usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function setvar_usage {
|
||||
declare -A HELP_VAR
|
||||
HELP_VAR["VM_OSREL"]="OS release to use in virtual machines"
|
||||
HELP_VAR["RUN_EXPERIMENTAL"]="Enforce execution of variants with EXPERIMENTAL variable set to \"true\""
|
||||
HELP_VAR["OPTIONAL_APTCACHER"]="build and Run tests will fail if apt-cacher not installed and this variable not set to \"true\""
|
||||
HELP_VAR["TESTPLATFORM_OWNER"]="Allow pipeline customization via execution of an externel scripts residing on the jenkins server"
|
||||
echo "--setvar_<varname> <value> where varname is one of:"
|
||||
for i in ${AUTHORIZED_VAR[@]}; do printf "%20s : %s\n" "$i" "${HELP_VAR[$i]}" ;done
|
||||
}
|
||||
|
||||
# functions variant__v<n>__<variant name> are used to define build or test variants
|
||||
# The only thing to do to define a new variant is to add a function which name
|
||||
# match this template. Note that "_" character in function <varriant name> part
|
||||
# will be replaced by "-" character in build_variant_arrays function, this is
|
||||
# for compatibility reasons
|
||||
|
||||
function variant__v1__enb_usrp {
|
||||
NB_PATTERN_FILES=7
|
||||
BUILD_OPTIONS="--eNB -w USRP --mu"
|
||||
VM_MEMORY=3072
|
||||
}
|
||||
|
||||
function variant__v2__basic_sim {
|
||||
NB_PATTERN_FILES=11
|
||||
BUILD_OPTIONS="--eNB --UE --noavx512"
|
||||
VM_MEMORY=8192
|
||||
RUN_OPTIONS="complex"
|
||||
}
|
||||
|
||||
function variant__v3__phy_sim {
|
||||
NB_PATTERN_FILES=11
|
||||
BUILD_OPTIONS="--phy_simulators"
|
||||
VM_MEMORY=8192
|
||||
VM_DISK=20
|
||||
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111 015112\" -q -np -b"
|
||||
}
|
||||
|
||||
function variant__v4__cppcheck {
|
||||
VM_MEMORY=4096
|
||||
LOG_PATTERN=cppcheck.xml
|
||||
NB_PATTERN_FILES=1
|
||||
BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 -i openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -I openair3/NAS/COMMON/UTIL -j4"
|
||||
}
|
||||
|
||||
function variant__v5__gnb_usrp {
|
||||
VM_MEMORY=10240
|
||||
VM_CPU=8
|
||||
NB_PATTERN_FILES=6
|
||||
BUILD_OPTIONS="--gNB -w USRP --noavx512"
|
||||
}
|
||||
|
||||
function variant__v6__nr_ue_usrp {
|
||||
VM_MEMORY=4096
|
||||
VM_CPU=4
|
||||
NB_PATTERN_FILES=6
|
||||
BUILD_OPTIONS="--nrUE -w USRP --noavx512"
|
||||
}
|
||||
|
||||
function variant__v7__enb_ethernet {
|
||||
VM_MEMORY=4096
|
||||
ARCHIVES_LOC=enb_eth
|
||||
NB_PATTERN_FILES=6
|
||||
BUILD_OPTIONS="--eNB -w USRP --noavx512"
|
||||
}
|
||||
|
||||
function variant__v8__ue_ethernet {
|
||||
VM_MEMORY=4096
|
||||
ARCHIVES_LOC=ue_eth
|
||||
NB_PATTERN_FILES=10
|
||||
BUILD_OPTIONS="--UE -w USRP --noavx512"
|
||||
}
|
||||
|
||||
function variant__v10__flexran_rtc {
|
||||
ARCHIVES_LOC=flexran
|
||||
NB_PATTERN_FILES=1
|
||||
BUILD_OPTIONS="cmake .. && make -j2"
|
||||
VARIANT_INFO="non-OSA"
|
||||
}
|
||||
|
||||
function variant__v20__l1_sim {
|
||||
ARCHIVES_LOC=l1_sim
|
||||
RUN_OPTIONS="complex"
|
||||
EXPERIMENTAL="true"
|
||||
}
|
||||
|
||||
function variant__v21__rf_sim {
|
||||
ARCHIVES_LOC=rf_sim
|
||||
RUN_OPTIONS="complex"
|
||||
}
|
||||
|
||||
function variant__v22__l2_sim {
|
||||
RUN_OPTIONS="complex"
|
||||
}
|
||||
|
||||
function variant__v23__rf5g_sim {
|
||||
ARCHIVES_LOC=rf5g_sim
|
||||
RUN_OPTIONS="complex"
|
||||
}
|
||||
|
||||
# Following function lists all variant__v<n>__<variant name> functions
|
||||
# and set the VARIANTS_SHORT and VARIANTS_LONG arrays from
|
||||
# the function names
|
||||
function build_variant_arrays {
|
||||
VARIANTS=`declare -F`
|
||||
VARIANTS=${VARIANTS//"declare -f "}
|
||||
for i in $VARIANTS
|
||||
do
|
||||
if [ `expr match "$i" 'variant__v'` -eq 10 ]
|
||||
then
|
||||
IDX1=`expr match "$i" 'variant__v[0-9]\+__'`
|
||||
VARIANTS_SHORT+=(${i:9:$((IDX1-11))})
|
||||
LONGNAME=${i:$IDX1}
|
||||
VARIANTS_LONG+=(${LONGNAME//"_"/"-"})
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# check that the passed argument is a valid variant, set
|
||||
# default values for variant related variables and then execute
|
||||
# the corresponding variant__v<n>__<variant name> function
|
||||
function check_set_variant {
|
||||
for (( i=0 ; i<${#VARIANTS_SHORT[@]} ; i++ ))
|
||||
do
|
||||
if [ "$1" = "${VARIANTS_SHORT[$i]}" ] || [ "$1" = "${VARIANTS_LONG[$i]}" ]
|
||||
then
|
||||
VM_NAME=ci-${VARIANTS_LONG[$i]}
|
||||
LOG_PATTERN=.txt
|
||||
ARCHIVES_LOC=${VARIANTS_LONG[$i]//"-"/"_"}
|
||||
VM_MEMORY=2048
|
||||
VM_CPU=4
|
||||
VM_DISK=10
|
||||
EXPERIMENTAL=""
|
||||
NBARGS=$[$NBARGS+$VARIANT_OPTID]
|
||||
variant__${VARIANTS_SHORT[$i]}__${VARIANTS_LONG[$i]//"-"/"_"}
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
echo "$1" is not a valid variant
|
||||
variant_usage
|
||||
exit 1
|
||||
|
||||
}
|
||||
|
||||
function check_command_options {
|
||||
GIVEN_OPTIONS=$1
|
||||
declare -a MANDATORY_OPTIONS=("${!2}")
|
||||
if [ ${MANDATORY_OPTIONS[1]} -eq 0 ]
|
||||
then
|
||||
MANDATORY_OPTIONS[1]=${MANDATORY_OPTIONS[0]}
|
||||
fi
|
||||
OPTIONAL_OPTIONS=$3
|
||||
if [ $(($GIVEN_OPTIONS & ${MANDATORY_OPTIONS[0]} )) -ne ${MANDATORY_OPTIONS[0]} ] && [ $(($GIVEN_OPTIONS & ${MANDATORY_OPTIONS[1]} )) -ne ${MANDATORY_OPTIONS[1]} ]
|
||||
then
|
||||
echo "Syntax Error: missing option(s) for $4 command"
|
||||
${4//-/_}_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $(( $(($GIVEN_OPTIONS ^ ${MANDATORY_OPTIONS[0]})) | $OPTIONAL_OPTIONS )) -ne $(( $OPTIONAL_OPTIONS )) ] && [ $(( $(($GIVEN_OPTIONS ^ ${MANDATORY_OPTIONS[1]})) | $OPTIONAL_OPTIONS )) -ne $(( $OPTIONAL_OPTIONS )) ]
|
||||
then
|
||||
echo "Syntax Error: unknown option(s) for $4 command"
|
||||
${4//-/_}_usage
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function check_ipv4addr {
|
||||
local ipaddr=$1
|
||||
local stat=1
|
||||
|
||||
if [[ $ipaddr =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]
|
||||
then
|
||||
OIFS=$IFS
|
||||
IFS='.'
|
||||
ipaddr=($ipaddr)
|
||||
IFS=$OIFS
|
||||
[[ ${ipaddr[0]} -le 255 && ${ipaddr[1]} -le 255 \
|
||||
&& ${ipaddr[2]} -le 255 && ${ipaddr[3]} -le 255 ]]
|
||||
stat=$?
|
||||
fi
|
||||
if [ $stat -ne 0 ]
|
||||
then
|
||||
echo $ipaddr " is not a valid ip V4 address"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function check_setvar {
|
||||
for i in ${AUTHORIZED_VAR[@]}
|
||||
do
|
||||
if [ "$1" = "$i" ]
|
||||
then
|
||||
echo "Setting $1 to $2..."
|
||||
export "$1"="$2"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
echo " $1 is not a variable you can set"
|
||||
setvar_usage
|
||||
exit 1
|
||||
}
|
||||
|
||||
platform_set
|
||||
MY_DIR=$(dirname $(readlink -f $0))
|
||||
. $MY_DIR/createVM.sh
|
||||
. $MY_DIR/buildOnVM.sh
|
||||
. $MY_DIR/waitBuildOnVM.sh
|
||||
. $MY_DIR/destroyAllRunningVM.sh
|
||||
. $MY_DIR/runTestOnVM.sh
|
||||
. $MY_DIR/reportBuildLocally.sh
|
||||
. $MY_DIR/reportTestLocally.sh
|
||||
|
||||
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo "Syntax Error: too few arguments"
|
||||
echo ""
|
||||
top_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VM_TEMPLATE=ci-
|
||||
|
||||
|
||||
# look for ASN1 release in cmake directives
|
||||
# It will be the release used when building
|
||||
ASN1VEROPT=( `grep "set (RRC_ASN1_VERSION" CMakeLists.txt` )
|
||||
ASN1VER=${ASN1VEROPT[2]//\"}
|
||||
ASN1VER=${ASN1VER//)}
|
||||
unset ASN1VEROPT
|
||||
|
||||
# variable to identify and store the command (build, create ...)
|
||||
# command index in the COMMAND and COMMANDS_NAME arrays
|
||||
HELP_CMD=0
|
||||
CREATE_CMD=1
|
||||
BUILD_CMD=2
|
||||
WAIT_CMD=3
|
||||
DESTROY_CMD=4
|
||||
TEST_CMD=5
|
||||
REPORT_BUILD_CMD=6
|
||||
REPORT_TEST_CMD=7
|
||||
|
||||
COMMANDS_NAME=(help create build wait destroy test report-build report-test)
|
||||
|
||||
#COMMAND will be used to save the command entered as argument
|
||||
declare -A COMMAND
|
||||
for i in "${COMMANDS_NAME[@]}"
|
||||
do
|
||||
COMMAND[$i]=0
|
||||
done
|
||||
|
||||
# build the variant arrays
|
||||
declare -a VARIANTS_SHORT
|
||||
declare -a VARIANTS_LONG
|
||||
build_variant_arrays
|
||||
|
||||
#variables to process options, for each option we define a variable to store
|
||||
# its value and a bit mask, used to check allowed options depending on
|
||||
# the command
|
||||
|
||||
# The two following arrays must be consistent: a given index must point to the long and short options
|
||||
# of a given command
|
||||
SHORT_OPTIONS=( "jn" "id" "ws" "k" "D" "gu" "pu" "mr" "var" "notused" "sb" "sc" "tb" "tc" "br" "co" "epc" "sim")
|
||||
LONG_OPTIONS=( "job-name" "build-id" "workspace" "keep-vm-alive" "daemon" "git-url" "push" "merge-request"
|
||||
"variant" "notused" "src-branch" "src-commit" "target-branch" "target-commit" "branch" "commit"
|
||||
"external-epc" "sim-file")
|
||||
|
||||
JOB_NAME=XX
|
||||
JOB_NAME_OPTINDEX=0
|
||||
JOB_NAME_OPTID=1
|
||||
|
||||
BUILD_ID=XX
|
||||
BUILD_ID_OPTINDEX=1
|
||||
BUILD_ID_OPTID=2
|
||||
|
||||
JENKINS_WKSP_OPTINDEX=2
|
||||
JENKINS_WKSP_OPTID=4
|
||||
|
||||
KEEP_VM_ALIVE_OPTINDEX=3
|
||||
KEEP_VM_ALIVE_OPTID=8
|
||||
KEEP_VM_ALIVE=0
|
||||
|
||||
DAEMON_OPTINDEX=4
|
||||
DAEMON_OPTID=$((2**4))
|
||||
DAEMON=0
|
||||
|
||||
GITURL_OPTINDEX=5
|
||||
GITURL_OPTID=$((2**5))
|
||||
|
||||
PU_OPTINDEX=6
|
||||
PU_OPTID=$((2**6))
|
||||
PU_TRIG=0
|
||||
|
||||
MR_OPTINDEX=7
|
||||
MR_OPTID=$((2**7))
|
||||
MR_TRIG=0
|
||||
|
||||
VARIANT_OPTINDEX=8
|
||||
VARIANT_OPTID=$((2**8))
|
||||
|
||||
SB_OPTINDEX=10
|
||||
SB_OPTID=$((2**10))
|
||||
|
||||
SC_OPTINDEX=11
|
||||
SC_OPTID=$((2**11))
|
||||
|
||||
TB_OPTINDEX=12
|
||||
TB_OPTID=$((2**12))
|
||||
|
||||
TC_OPTINDEX=13
|
||||
TC_OPTID=$((2**13))
|
||||
|
||||
BR_OPTINDEX=14
|
||||
BR_OPTID=$((2**14))
|
||||
|
||||
CO_OPTINDEX=15
|
||||
CO_OPTID=$((2**15))
|
||||
|
||||
EPC_IPADDR_OPTINDEX=16
|
||||
EPC_IPADDR_OPTID=$((2**16))
|
||||
EPC_IPADDR=""
|
||||
|
||||
SIM_OPTINDEX=17
|
||||
SIM_OPTID=$((2**17))
|
||||
SIMFILE=""
|
||||
|
||||
RUN_OPTIONS="none"
|
||||
|
||||
|
||||
# list of variables that can be set via the --setvar option
|
||||
AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL OPTIONAL_APTCACHER TESTPLATFORM_OWNER")
|
||||
|
||||
|
||||
#variables to set which OS VM should use
|
||||
#if [ -f "/etc/os-release" ]
|
||||
#then
|
||||
# source /etc/os-release
|
||||
# VM_OS="$NAME"
|
||||
# VM_OSREL="$VERSION_CODENAME"
|
||||
# VM_ARCHI=`uname -m`
|
||||
#else
|
||||
VM_OS="ubuntu"
|
||||
VM_OSREL="xenial"
|
||||
VM_ARCHI="x86_64"
|
||||
#fi
|
||||
|
||||
|
||||
# variant option, ie the test variant which will be run triggers the
|
||||
# variables listed below, used to configure the VM and to define what this
|
||||
# VM will do. The variant can be specified by the --variant option or by a
|
||||
# -V<xx> option.
|
||||
VM_NAME=""
|
||||
VM_MEMORY=0
|
||||
VM_DISK=0
|
||||
VM_CPU=0
|
||||
ARCHIVES_LOC=""
|
||||
LOG_PATTERN=""
|
||||
NB_PATTERN_FILES=0
|
||||
BUILD_OPTIONS=""
|
||||
RUN_OPTIONS=""
|
||||
|
||||
|
||||
|
||||
# NARGS is used to check that only valid options are used for the given command
|
||||
# It is a bit mask, each bit set to 1 specifies the corresponding option
|
||||
# has been entered on the command line. MANDATORY_OPTMASK and ALLOWED_OPTMASK define
|
||||
# respectively the mandatory and optional parameters of the entered command
|
||||
NBARGS=0
|
||||
MANDATORY_OPTMASK=(0 0) # some command have two sets of mandatory options
|
||||
ALLOWED_OPTMASK=0
|
||||
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
key="$1"
|
||||
|
||||
if [ "$(type -t $funcname)" != 'function' ]; then
|
||||
funcname=do_it_normal
|
||||
fi
|
||||
case $key in
|
||||
--debug)
|
||||
set -v
|
||||
set -x
|
||||
shift
|
||||
;;
|
||||
-h|--help|help)
|
||||
COMMAND["help"]=1
|
||||
# following word might specify the topic for the help request
|
||||
# but help can also be used without argument, so don't shift
|
||||
if [ "$2" != "" ] && [ "$(type -t ${2//-/_}_usage)" = 'function' ]
|
||||
then
|
||||
HELPCMD="${2//-/_}_usage full"
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
create)
|
||||
COMMAND[$key]=1
|
||||
# For create, mandatory options: jn, id. Optional: variant
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID ))
|
||||
ALLOWED_OPTMASK=$(($VARIANT_OPTID))
|
||||
# It is implied to keep the VM when creating it
|
||||
KEEP_VM_ALIVE=1
|
||||
shift
|
||||
;;
|
||||
build)
|
||||
COMMAND[$key]=1
|
||||
# For build, mandatory options: jn, id, ws. Optional: variant, k, D
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
|
||||
ALLOWED_OPTMASK=$(($KEEP_VM_ALIVE_OPTID + $DAEMON_OPTID + $VARIANT_OPTID))
|
||||
shift
|
||||
;;
|
||||
wait)
|
||||
# For test, mandatory options: jn, id, ws. Optional: variant, k
|
||||
COMMAND[$key]=1
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
|
||||
ALLOWED_OPTMASK=$(($KEEP_VM_ALIVE_OPTID + $VARIANT_OPTID))
|
||||
shift
|
||||
;;
|
||||
test)
|
||||
COMMAND[$key]=1
|
||||
# For test, mandatory options: jn, id, ws. Optional: variant, k, epc
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
|
||||
ALLOWED_OPTMASK=$(($KEEP_VM_ALIVE_OPTID + $VARIANT_OPTID + $EPC_IPADDR_OPTID + $SIM_OPTID))
|
||||
shift
|
||||
;;
|
||||
destroy)
|
||||
COMMAND[$key]=1
|
||||
# For destroy, mandatory options: jn, id.
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID))
|
||||
shift
|
||||
;;
|
||||
report-build)
|
||||
COMMAND[$key]=1
|
||||
# For report-build, mandatory options: jn, id, ws, gu, pu, br,co.
|
||||
# or: jn, id, ws, gu, mr, sb, sc, tb, tc.
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID + $GITURL_OPTID + $PU_OPTID + $BR_OPTID + $CO_OPTID))
|
||||
MANDATORY_OPTMASK[1]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID + $GITURL_OPTID + $MR_OPTID + $SB_OPTID + $SC_OPTID))
|
||||
MANDATORY_OPTMASK[1]=$(( ${MANDATORY_OPTMASK[1]} + $TB_OPTID + $TC_OPTID))
|
||||
shift
|
||||
;;
|
||||
report-test)
|
||||
COMMAND[$key]=1
|
||||
# For report-test, mandatory options: jn, id, ws, gu, pu, br,co.
|
||||
# or: jn, id, ws, gu, mr, sb, sc, tb, tc.
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
|
||||
MANDATORY_OPTMASK[0]=$((${MANDATORY_OPTMASK[0]} + $GITURL_OPTID + $PU_OPTID + $BR_OPTID + $CO_OPTID))
|
||||
MANDATORY_OPTMASK[1]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
|
||||
MANDATORY_OPTMASK[1]=$((${MANDATORY_OPTMASK[1]} + GITURL_OPTID + $MR_OPTID + $SB_OPTID + $SC_OPTID))
|
||||
MANDATORY_OPTMASK[1]=$((${MANDATORY_OPTMASK[1]} + $TB_OPTID + $TC_OPTID))
|
||||
shift
|
||||
;;
|
||||
-jn|--job-name)
|
||||
JOB_NAME="$2"
|
||||
NBARGS=$[$NBARGS+$JOB_NAME_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-id|--build-id)
|
||||
BUILD_ID="$2"
|
||||
NBARGS=$[$NBARGS+$BUILD_ID_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-ws|--workspace)
|
||||
JENKINS_WKSP="$2"
|
||||
NBARGS=$[$NBARGS+$JENKINS_WKSP_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-k|--keep-vm-alive)
|
||||
KEEP_VM_ALIVE=1
|
||||
NBARGS=$[$NBARGS+$KEEP_VM_ALIVE_OPTID]
|
||||
shift
|
||||
;;
|
||||
-D|--daemon)
|
||||
DAEMON=1
|
||||
NBARGS=$[$NBARGS+$DAEMON_OPTID]
|
||||
shift
|
||||
;;
|
||||
-gu|--git-url)
|
||||
GIT_URL="$2"
|
||||
NBARGS=$[$NBARGS+$GITURL_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--trigger)
|
||||
TRIG="$2"
|
||||
case $TRIG in
|
||||
merge-request)
|
||||
MR_TRIG=1
|
||||
NBARGS=$[$NBARGS+$MR_OPTID]
|
||||
;;
|
||||
push)
|
||||
PU_TRIG=1
|
||||
NBARGS=$[$NBARGS+$PU_OPTID]
|
||||
;;
|
||||
*)
|
||||
echo ""
|
||||
echo "Syntax Error: Invalid Trigger option -> $TRIG"
|
||||
echo ""
|
||||
trigger_usage
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-mr|--merge-request)
|
||||
MR_TRIG=1
|
||||
NBARGS=$[$NBARGS+$MR_OPTID]
|
||||
shift
|
||||
;;
|
||||
-pu|--push)
|
||||
PU_TRIG=1
|
||||
NBARGS=$[$NBARGS+$PU_OPTID]
|
||||
shift
|
||||
;;
|
||||
-sb|--src-branch)
|
||||
SOURCE_BRANCH="$2"
|
||||
NBARGS=$[$NBARGS+$SB_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-sc|--src-commit)
|
||||
SOURCE_COMMIT_ID="$2"
|
||||
NBARGS=$[$NBARGS+$SC_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-tb|--target-branch)
|
||||
TARGET_BRANCH="$2"
|
||||
NBARGS=$[$NBARGS+$TB_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-tc|--target-commit)
|
||||
TARGET_COMMIT_ID="$2"
|
||||
NBARGS=$[$NBARGS+$TC_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-br|--branch)
|
||||
SOURCE_BRANCH="$2"
|
||||
NBARGS=$[$NBARGS+$BR_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-co|--commit)
|
||||
SOURCE_COMMIT_ID="$2"
|
||||
NBARGS=$[$NBARGS+$CO_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-epc|--external-epc)
|
||||
check_ipv4addr "$2"
|
||||
check_ipv4addr "$3"
|
||||
EPC_IPADDR="$2"
|
||||
EPC_TUN_IPADDR="$3"
|
||||
NBARGS=$[$NBARGS+$EPC_IPADDR_OPTID]
|
||||
shift
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-sim|--sim-file)
|
||||
SIMFILE="$2"
|
||||
NBARGS=$[$NBARGS+$SIM_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--setvar_*)
|
||||
check_setvar "${key:9}" "$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-v[0-9] | -v[0-9][0-9])
|
||||
check_set_variant ${key//"-"}
|
||||
shift
|
||||
;;
|
||||
-var|--variant)
|
||||
variant="$2"
|
||||
check_set_variant ${2}
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Syntax Error: unknown option: $key"
|
||||
echo ""
|
||||
top_usage
|
||||
exit 1
|
||||
esac
|
||||
done
|
||||
|
||||
i=0
|
||||
for (( COUNT=1 ; COUNT<${#COMMAND[@]} ; COUNT++ ))
|
||||
do
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$COUNT]}]} -eq 1 ]
|
||||
then
|
||||
COMMAND_KEY[$i]=${COMMANDS_NAME[$COUNT]}
|
||||
(( i++ ))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${COMMAND["help"]} -eq 1 ]
|
||||
then
|
||||
if [ ${#COMMAND_KEY[@]} -ne 1 ] && [ "$HELPCMD" == "" ]
|
||||
then
|
||||
top_usage
|
||||
elif [ "$HELPCMD" != "" ]
|
||||
then
|
||||
$HELPCMD
|
||||
else
|
||||
${COMMAND_KEY[0]//-/_}_usage
|
||||
fi
|
||||
exit 0
|
||||
else
|
||||
if [ ${#COMMAND_KEY[@]} -gt 1 ]
|
||||
then
|
||||
echo "Syntax Error, too many commands: ${COMMAND_KEY[@]}"
|
||||
top_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "${COMMAND_KEY[0]}" ]
|
||||
then
|
||||
echo "Syntax Error: no command, specify one of: ${COMMANDS_NAME[@]}"
|
||||
top_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
check_command_options $NBARGS MANDATORY_OPTMASK[@] $ALLOWED_OPTMASK ${COMMAND_KEY[0]}
|
||||
fi
|
||||
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$REPORT_BUILD_CMD]}]} -ne 1 ] && [ ${COMMAND[${COMMANDS_NAME[$REPORT_TEST_CMD]}]} -ne 1 ]
|
||||
then
|
||||
# Checking uvt-kvm is installed
|
||||
UVT_KVM_PATH=`which uvt-kvm | grep -c uvt-kvm`
|
||||
if [ $UVT_KVM_PATH -eq 0 ]
|
||||
then
|
||||
echo "Error: uvt-kvm is not installed"
|
||||
top_usage
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ]
|
||||
then
|
||||
VM_TEMPLATE=ci-
|
||||
else
|
||||
VM_TEMPLATE=${JOB_NAME}-b${BUILD_ID}-
|
||||
fi
|
||||
# set default variant
|
||||
if [ "$VM_NAME" = "" ]
|
||||
then
|
||||
check_set_variant "v1"
|
||||
fi
|
||||
VM_NAME=`echo $VM_NAME | sed -e "s#ci-#$VM_TEMPLATE#"`
|
||||
VM_CMDS=${VM_NAME}_cmds.txt
|
||||
ARCHIVES_LOC=${JENKINS_WKSP}/archives/${ARCHIVES_LOC}
|
||||
|
||||
STATUS=0
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$CREATE_CMD]}]} -eq 1 ]
|
||||
then
|
||||
if [[ "$BUILD_OPTIONS" = "" ]]
|
||||
then
|
||||
echo "$VM_NAME is not a build variant"
|
||||
exit 0
|
||||
else
|
||||
create_vm
|
||||
fi
|
||||
fi
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$BUILD_CMD]}]} -eq 1 ]
|
||||
then
|
||||
if [[ "$BUILD_OPTIONS" = "" ]]
|
||||
then
|
||||
echo " $VM_NAME is not a build variant"
|
||||
exit 0
|
||||
else
|
||||
build_on_vm
|
||||
fi
|
||||
if [ $DAEMON -eq 0 ] && [ $STATUS -eq 0 ]
|
||||
then
|
||||
check_on_vm_build
|
||||
fi
|
||||
fi
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$WAIT_CMD]}]} -eq 1 ]
|
||||
then
|
||||
if [[ "$BUILD_OPTIONS" = "" ]]
|
||||
then
|
||||
echo "$VM_NAME is not a build variant"
|
||||
exit 0
|
||||
else
|
||||
wait_on_vm_build
|
||||
fi
|
||||
if [ $STATUS -eq 0 ]
|
||||
then
|
||||
check_on_vm_build
|
||||
fi
|
||||
fi
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$TEST_CMD]}]} -eq 1 ]
|
||||
then
|
||||
# variant with EXPERIMENTAL variable set to true won't run and will be
|
||||
# considered OK, except if --setvar_RUN_EXPERIMENTAL option has been set to true
|
||||
if [ "$EXPERIMENTAL" = "true" ] && [ "$RUN_EXPERIMENTAL" != "true" ]
|
||||
then
|
||||
echo "Currently $VM_NAME Testing is not implemented / enabled"
|
||||
echo "remove EXPERIMENTAL variable definition from this variant"
|
||||
echo " or use option --setvar_RUN_EXPERIMENTAL=true to enforce testing it"
|
||||
echo "STATUS seems OK"
|
||||
exit $STATUS
|
||||
fi
|
||||
|
||||
ARCHIVES_LOC=${ARCHIVES_LOC}/test
|
||||
run_test_on_vm
|
||||
fi
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$DESTROY_CMD]}]} -eq 1 ]
|
||||
then
|
||||
destroy_vm
|
||||
fi
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$REPORT_BUILD_CMD]}]} -eq 1 ]
|
||||
then
|
||||
report_build
|
||||
fi
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$REPORT_TEST_CMD]}]} -eq 1 ]
|
||||
then
|
||||
report_test
|
||||
fi
|
||||
|
||||
# Did command pass or fail?
|
||||
if [ $STATUS -eq 0 ]
|
||||
then
|
||||
echo "STATUS seems OK"
|
||||
else
|
||||
echo "STATUS failed?"
|
||||
fi
|
||||
exit $STATUS
|
||||
@@ -1,613 +0,0 @@
|
||||
#!/bin/bash
|
||||
#/*
|
||||
# * 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
|
||||
# */
|
||||
|
||||
function report_build_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo " oai-ci-vm-tool report-build [OPTIONS]"
|
||||
echo ""
|
||||
command_options_usage
|
||||
|
||||
}
|
||||
|
||||
function trigger_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo ""
|
||||
echo " --trigger merge-request OR -mr"
|
||||
echo " --trigger push OR -pu"
|
||||
echo " Specify trigger action of the Jenkins job. Either a merge-request event or a push event."
|
||||
echo ""
|
||||
}
|
||||
|
||||
function details_table {
|
||||
echo " <h4>$1</h4>" >> $3
|
||||
|
||||
echo " <table border = \"1\">" >> $3
|
||||
echo " <tr bgcolor = \"#33CCFF\" >" >> $3
|
||||
echo " <th>File</th>" >> $3
|
||||
echo " <th>Line Number</th>" >> $3
|
||||
echo " <th>Status</th>" >> $3
|
||||
echo " <th>Message</th>" >> $3
|
||||
echo " </tr>" >> $3
|
||||
|
||||
LIST_MESSAGES=`egrep "error:|warning:" $2 | egrep -v "jobserver unavailable|Clock skew detected.|disabling jobserver mode"`
|
||||
COMPLETE_MESSAGE="start"
|
||||
for MESSAGE in $LIST_MESSAGES
|
||||
do
|
||||
if [[ $MESSAGE == *"/home/ubuntu/tmp"* ]] || [[ $MESSAGE == *"/tmp/CI-eNB"* ]]
|
||||
then
|
||||
FILENAME=`echo $MESSAGE | sed -e "s#^/home/ubuntu/tmp/##" -e "s#^.*/tmp/CI-eNB/##" | awk -F ":" '{print $1}'`
|
||||
LINENB=`echo $MESSAGE | awk -F ":" '{print $2}'`
|
||||
if [ "$COMPLETE_MESSAGE" != "start" ]
|
||||
then
|
||||
COMPLETE_MESSAGE=`echo $COMPLETE_MESSAGE | sed -e "s#‘#'#g" -e "s#’#'#g"`
|
||||
echo " <td>$COMPLETE_MESSAGE</td>" >> $3
|
||||
echo " </tr>" >> $3
|
||||
fi
|
||||
echo " <tr>" >> $3
|
||||
echo " <td>$FILENAME</td>" >> $3
|
||||
echo " <td>$LINENB</td>" >> $3
|
||||
else
|
||||
if [[ $MESSAGE == *"warning:"* ]] || [[ $MESSAGE == *"error:"* ]]
|
||||
then
|
||||
MSGTYPE=`echo $MESSAGE | sed -e "s#:##g"`
|
||||
echo " <td>$MSGTYPE</td>" >> $3
|
||||
COMPLETE_MESSAGE=""
|
||||
else
|
||||
COMPLETE_MESSAGE=$COMPLETE_MESSAGE" "$MESSAGE
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$COMPLETE_MESSAGE" != "start" ]
|
||||
then
|
||||
COMPLETE_MESSAGE=`echo $COMPLETE_MESSAGE | sed -e "s#‘#'#g" -e "s#’#'#g"`
|
||||
echo " <td>$COMPLETE_MESSAGE</td>" >> $3
|
||||
echo " </tr>" >> $3
|
||||
fi
|
||||
echo " </table>" >> $3
|
||||
}
|
||||
|
||||
function summary_table_header {
|
||||
echo " <h3>$1</h3>" >> ./build_results.html
|
||||
if [ -f $2/build_final_status.log ]
|
||||
then
|
||||
if [ `grep -c COMMAND $2/build_final_status.log` -eq 1 ]
|
||||
then
|
||||
COMMAND=`grep COMMAND $2/build_final_status.log | sed -e "s#COMMAND: ##"`
|
||||
else
|
||||
COMMAND="Unknown"
|
||||
fi
|
||||
if [ `grep -c BUILD_OK $2/build_final_status.log` -eq 1 ]
|
||||
then
|
||||
echo " <div class=\"alert alert-success\">" >> ./build_results.html
|
||||
echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <span class=\"glyphicon glyphicon-arrow-right\"></span> " >> ./build_results.html
|
||||
echo " <strong>BUILD was SUCCESSFUL <span class=\"glyphicon glyphicon-ok-circle\"></span></strong>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
else
|
||||
echo " <div class=\"alert alert-danger\">" >> ./build_results.html
|
||||
echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <span class=\"glyphicon glyphicon-arrow-right\"></span> " >> ./build_results.html
|
||||
echo " <strong>BUILD was a FAILURE! <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
fi
|
||||
else
|
||||
echo " <div class=\"alert alert-danger\">" >> ./build_results.html
|
||||
echo " <strong>COULD NOT DETERMINE BUILD FINAL STATUS! <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
fi
|
||||
echo " <table border = \"1\">" >> ./build_results.html
|
||||
echo " <tr bgcolor = \"#33CCFF\" >" >> ./build_results.html
|
||||
echo " <th>Element</th>" >> ./build_results.html
|
||||
echo " <th>Status</th>" >> ./build_results.html
|
||||
echo " <th>Nb Errors</th>" >> ./build_results.html
|
||||
echo " <th>Nb Warnings</th>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
}
|
||||
|
||||
function summary_table_row {
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" >$1</th>" >> ./build_results.html
|
||||
if [ -f $2 ]
|
||||
then
|
||||
BUILD_STATUS=`egrep -c "$3" $2`
|
||||
if [ $BUILD_STATUS -eq 1 ]
|
||||
then
|
||||
echo " <td bgcolor = \"green\" >OK</th>" >> ./build_results.html
|
||||
else
|
||||
echo " <td bgcolor = \"red\" >KO</th>" >> ./build_results.html
|
||||
fi
|
||||
NB_ERRORS=`egrep -c "error:" $2`
|
||||
if [ $NB_ERRORS -eq 0 ]
|
||||
then
|
||||
echo " <td bgcolor = \"green\" >$NB_ERRORS</th>" >> ./build_results.html
|
||||
else
|
||||
echo " <td bgcolor = \"red\" >$NB_ERRORS</th>" >> ./build_results.html
|
||||
fi
|
||||
NB_WARNINGS=`egrep "warning:" $2 | egrep -v "jobserver unavailable|Clock skew detected.|disabling jobserver mode" | egrep -c "warning:"`
|
||||
if [ $NB_WARNINGS -eq 0 ]
|
||||
then
|
||||
echo " <td bgcolor = \"green\" >$NB_WARNINGS</th>" >> ./build_results.html
|
||||
else
|
||||
if [ $NB_WARNINGS -gt 20 ]
|
||||
then
|
||||
echo " <td bgcolor = \"red\" >$NB_WARNINGS</th>" >> ./build_results.html
|
||||
else
|
||||
echo " <td bgcolor = \"orange\" >$NB_WARNINGS</th>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
if [ $NB_ERRORS -ne 0 ] || [ $NB_WARNINGS -ne 0 ]
|
||||
then
|
||||
details_table "$1" $2 $4
|
||||
fi
|
||||
else
|
||||
echo " <td bgcolor = \"lightgray\" >Unknown</th>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightgray\" >--</th>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightgray\" >--</th>" >> ./build_results.html
|
||||
fi
|
||||
echo " </tr>" >> ./build_results.html
|
||||
}
|
||||
|
||||
function summary_table_footer {
|
||||
echo " </table>" >> ./build_results.html
|
||||
}
|
||||
|
||||
function sca_summary_table_header {
|
||||
echo " <h3>$2</h3>" >> ./build_results.html
|
||||
NB_ERRORS=`egrep -c "severity=\"error\"" $1`
|
||||
NB_WARNINGS=`egrep -c "severity=\"warning\"" $1`
|
||||
ADDED_ERRORS="0"
|
||||
ADDED_WARNINGS="0"
|
||||
FINAL_LOG=`echo $1 | sed -e "s#cppcheck\.xml#build_final_status.log#"`
|
||||
if [ `grep -c COMMAND $FINAL_LOG` -eq 1 ]
|
||||
then
|
||||
COMMAND=`grep COMMAND $FINAL_LOG | sed -e "s#COMMAND: ##"`
|
||||
else
|
||||
COMMAND="Unknown"
|
||||
fi
|
||||
if [ $MR_TRIG -eq 1 ]
|
||||
then
|
||||
if [ -d ../../cppcheck_archives ]
|
||||
then
|
||||
if [ -d ../../cppcheck_archives/$JOB_NAME ]
|
||||
then
|
||||
ADDED_ERRORS=`diff $1 ../../cppcheck_archives/$JOB_NAME/cppcheck.xml | egrep --color=never "^<" | egrep -c "severity=\"error"`
|
||||
ADDED_WARNINGS=`diff $1 ../../cppcheck_archives/$JOB_NAME/cppcheck.xml | egrep --color=never "^<" | egrep -c "severity=\"warning"`
|
||||
fi
|
||||
fi
|
||||
local TOTAL_NUMBER=$[$ADDED_ERRORS+$ADDED_WARNINGS]
|
||||
if [ -f $JENKINS_WKSP/oai_cppcheck_added_errors.txt ]; then rm -f $JENKINS_WKSP/oai_cppcheck_added_errors.txt; fi
|
||||
echo "$TOTAL_NUMBER" > $JENKINS_WKSP/oai_cppcheck_added_errors.txt
|
||||
fi
|
||||
if [ $NB_ERRORS -eq 0 ] && [ $NB_WARNINGS -eq 0 ]
|
||||
then
|
||||
echo " <div class=\"alert alert-success\">" >> ./build_results.html
|
||||
echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <br><br>" >> ./build_results.html
|
||||
echo " <strong>CPPCHECK found NO error and NO warning <span class=\"glyphicon glyphicon-ok-circle\"></span></strong>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
else
|
||||
if [ $NB_ERRORS -eq 0 ]
|
||||
then
|
||||
echo " <div class=\"alert alert-warning\">" >> ./build_results.html
|
||||
echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <br><br>" >> ./build_results.html
|
||||
if [ $PU_TRIG -eq 1 ]
|
||||
then
|
||||
echo " <strong>CPPCHECK found NO error and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-warning-sign\"></span></strong>" >> ./build_results.html
|
||||
fi
|
||||
if [ $MR_TRIG -eq 1 ]
|
||||
then
|
||||
if [ $ADDED_WARNINGS -eq 0 ]
|
||||
then
|
||||
echo " <strong>CPPCHECK found NO error and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-warning-sign\"></span></strong>" >> ./build_results.html
|
||||
else
|
||||
echo " <strong>CPPCHECK found NO error and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-warning-sign\"></span></strong>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
else
|
||||
echo " <div class=\"alert alert-danger\">" >> ./build_results.html
|
||||
echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <br><br>" >> ./build_results.html
|
||||
if [ $PU_TRIG -eq 1 ]
|
||||
then
|
||||
echo " <strong>CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./build_results.html
|
||||
fi
|
||||
if [ $MR_TRIG -eq 1 ]
|
||||
then
|
||||
if [ $ADDED_ERRORS -eq 0 ] && [ $ADDED_WARNINGS -eq 0 ]
|
||||
then
|
||||
echo " <strong>CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./build_results.html
|
||||
else
|
||||
echo " <strong>CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-ban-circle\"></span>" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
echo " <span class=\"glyphicon glyphicon-alert\"></span> This Merge Request may have introduced up to $ADDED_ERRORS errors and $ADDED_WARNINGS warnings. <span class=\"glyphicon glyphicon-alert\"></span></strong>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
if [ $PU_TRIG -eq 1 ]
|
||||
then
|
||||
if [ -d ../../cppcheck_archives ]
|
||||
then
|
||||
if [ -d ../../cppcheck_archives/$JOB_NAME ]
|
||||
then
|
||||
cp $1 ../../cppcheck_archives/$JOB_NAME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo " <button data-toggle=\"collapse\" data-target=\"#oai-cppcheck-details\">More details on CPPCHECK results</button>" >> ./build_results.html
|
||||
echo " <div id=\"oai-cppcheck-details\" class=\"collapse\">" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
echo " <table border = \"1\">" >> ./build_results.html
|
||||
echo " <tr bgcolor = \"#33CCFF\" >" >> ./build_results.html
|
||||
echo " <th>Error / Warning Type</th>" >> ./build_results.html
|
||||
echo " <th>Nb Errors</th>" >> ./build_results.html
|
||||
echo " <th>Nb Warnings</th>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo "0" > ccp_error_cnt.txt
|
||||
}
|
||||
|
||||
function sca_summary_table_row {
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" >$2</td>" >> ./build_results.html
|
||||
if [ -f $1 ]
|
||||
then
|
||||
NB_ERRORS=`egrep "severity=\"error\"" $1 | egrep -c "id=\"$3\""`
|
||||
echo " <td>$NB_ERRORS</td>" >> ./build_results.html
|
||||
echo " <td>N/A</td>" >> ./build_results.html
|
||||
if [ -f ccp_error_cnt.txt ]
|
||||
then
|
||||
TOTAL_ERRORS=`cat ccp_error_cnt.txt`
|
||||
TOTAL_ERRORS=$((TOTAL_ERRORS + NB_ERRORS))
|
||||
echo $TOTAL_ERRORS > ccp_error_cnt.txt
|
||||
fi
|
||||
else
|
||||
echo " <td>Unknown</td>" >> ./build_results.html
|
||||
echo " <td>Unknown</td>" >> ./build_results.html
|
||||
fi
|
||||
echo " </tr>" >> ./build_results.html
|
||||
}
|
||||
|
||||
function sca_summary_table_footer {
|
||||
if [ -f $1 ]
|
||||
then
|
||||
NB_ERRORS=`egrep -c "severity=\"error\"" $1`
|
||||
NB_WARNINGS=`egrep -c "severity=\"warning\"" $1`
|
||||
if [ -f ccp_error_cnt.txt ]
|
||||
then
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" >Others</td>" >> ./build_results.html
|
||||
TOTAL_ERRORS=`cat ccp_error_cnt.txt`
|
||||
TOTAL_ERRORS=$((NB_ERRORS - TOTAL_ERRORS))
|
||||
echo " <td>$TOTAL_ERRORS</td>" >> ./build_results.html
|
||||
echo " <td>$NB_WARNINGS</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
rm -f ccp_error_cnt.txt
|
||||
fi
|
||||
echo " <tr bgcolor = \"#33CCFF\" >" >> ./build_results.html
|
||||
echo " <th>Total</th>" >> ./build_results.html
|
||||
echo " <th>$NB_ERRORS</th>" >> ./build_results.html
|
||||
echo " <th>$NB_WARNINGS</th>" >> ./build_results.html
|
||||
else
|
||||
echo " <tr bgcolor = \"#33CCFF\" >" >> ./build_results.html
|
||||
echo " <th>Total</th>" >> ./build_results.html
|
||||
echo " <th>Unknown</th>" >> ./build_results.html
|
||||
echo " <th>Unknown</th>" >> ./build_results.html
|
||||
if [ -f ccp_error_cnt.txt ]
|
||||
then
|
||||
rm -f ccp_error_cnt.txt
|
||||
fi
|
||||
fi
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " </table>" >> ./build_results.html
|
||||
echo " <p>Full details in zipped artifact (cppcheck/cppcheck.xml) </p>" >> ./build_results.html
|
||||
echo " <p style=\"margin-left: 30px\">Graphical Interface tool : <strong><code>cppcheck-gui -l cppcheck/cppcheck.xml</code></strong></p>" >> ./build_results.html
|
||||
|
||||
if [ $MR_TRIG -eq 1 ]
|
||||
then
|
||||
if [ $ADDED_ERRORS -ne 0 ] || [ $ADDED_WARNINGS -ne 0 ]
|
||||
then
|
||||
echo " <table border = \"1\">" >> ./build_results.html
|
||||
echo " <tr bgcolor = \"#33CCFF\" >" >> ./build_results.html
|
||||
echo " <th>Potential File(s) impacted by added errors/warnings</th>" >> ./build_results.html
|
||||
echo " <th>Line Number</th>" >> ./build_results.html
|
||||
echo " <th>Severity</th>" >> ./build_results.html
|
||||
echo " <th>Message</th>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
SEVERITY="none"
|
||||
POTENTIAL_FILES=`diff $1 ../../cppcheck_archives/$JOB_NAME/cppcheck.xml | egrep --color=never "^<" | egrep "location file|severity" | sed -e "s# #@#g"`
|
||||
for POT_FILE in $POTENTIAL_FILES
|
||||
do
|
||||
if [ `echo $POT_FILE | grep -c location` -eq 1 ]
|
||||
then
|
||||
FILENAME=`echo $POT_FILE | sed -e "s#^.*file=\"##" -e "s#\"@line.*/>##"`
|
||||
LINE=`echo $POT_FILE | sed -e "s#^.*line=\"##" -e "s#\"/>##"`
|
||||
if [[ $SEVERITY != *"none" ]]
|
||||
then
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td>$FILENAME</td>" >> ./build_results.html
|
||||
echo " <td>$LINE</td>" >> ./build_results.html
|
||||
echo " <td>$SEVERITY</td>" >> ./build_results.html
|
||||
echo " <td>$MESSAGE</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
fi
|
||||
else
|
||||
SEVERITY=`echo $POT_FILE | sed -e "s#^.*severity=\"##" -e "s#\"@msg=.*##"`
|
||||
MESSAGE=`echo $POT_FILE | sed -e "s#^.*msg=\"##" -e "s#\"@verbose=.*##" -e "s#@# #g"`
|
||||
fi
|
||||
done
|
||||
echo " </table>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
}
|
||||
|
||||
function report_build {
|
||||
echo "############################################################"
|
||||
echo "OAI CI VM script"
|
||||
echo "############################################################"
|
||||
|
||||
echo "JENKINS_WKSP = $JENKINS_WKSP"
|
||||
echo "GIT_URL = $GIT_URL"
|
||||
|
||||
cd ${JENKINS_WKSP}
|
||||
echo "<!DOCTYPE html>" > ./build_results.html
|
||||
echo "<html class=\"no-js\" lang=\"en-US\">" >> ./build_results.html
|
||||
echo "<head>" >> ./build_results.html
|
||||
echo " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" >> ./build_results.html
|
||||
echo " <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css\">" >> ./build_results.html
|
||||
echo " <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>" >> ./build_results.html
|
||||
echo " <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js\"></script>" >> ./build_results.html
|
||||
echo " <title>Build Results for $JOB_NAME job build #$BUILD_ID</title>" >> ./build_results.html
|
||||
echo " <base href = \"http://www.openairinterface.org/\" />" >> ./build_results.html
|
||||
echo "</head>" >> ./build_results.html
|
||||
echo "<body><div class=\"container\">" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
echo " <table style=\"border-collapse: collapse; border: none;\">" >> ./build_results.html
|
||||
echo " <tr style=\"border-collapse: collapse; border: none;\">" >> ./build_results.html
|
||||
echo " <td style=\"border-collapse: collapse; border: none;\">" >> ./build_results.html
|
||||
echo " <a href=\"http://www.openairinterface.org/\">" >> ./build_results.html
|
||||
echo " <img src=\"/wp-content/uploads/2016/03/cropped-oai_final_logo2.png\" alt=\"\" border=\"none\" height=50 width=150>" >> ./build_results.html
|
||||
echo " </img>" >> ./build_results.html
|
||||
echo " </a>" >> ./build_results.html
|
||||
echo " </td>" >> ./build_results.html
|
||||
echo " <td style=\"border-collapse: collapse; border: none; vertical-align: center;\">" >> ./build_results.html
|
||||
echo " <b><font size = \"6\">Job Summary -- Job: $JOB_NAME -- Build-ID: $BUILD_ID</font></b>" >> ./build_results.html
|
||||
echo " </td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " </table>" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
echo " <table border = \"1\">" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-time\"></span> Build Start Time (UTC)</td>" >> ./build_results.html
|
||||
echo " <td>TEMPLATE_BUILD_TIME</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-cloud-upload\"></span> GIT Repository</td>" >> ./build_results.html
|
||||
echo " <td><a href=\"$GIT_URL\">$GIT_URL</a></td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-wrench\"></span> Job Trigger</td>" >> ./build_results.html
|
||||
if [ $PU_TRIG -eq 1 ]; then echo " <td>Push Event</td>" >> ./build_results.html; fi
|
||||
if [ $MR_TRIG -eq 1 ]; then echo " <td>Merge-Request</td>" >> ./build_results.html; fi
|
||||
echo " </tr>" >> ./build_results.html
|
||||
if [ $PU_TRIG -eq 1 ]
|
||||
then
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-tree-deciduous\"></span> Branch</td>" >> ./build_results.html
|
||||
echo " <td>$SOURCE_BRANCH</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-tag\"></span> Commit ID</td>" >> ./build_results.html
|
||||
echo " <td>$SOURCE_COMMIT_ID</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
if [ -e .git/CI_COMMIT_MSG ]
|
||||
then
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-comment\"></span> Commit Message</td>" >> ./build_results.html
|
||||
MSG=`cat .git/CI_COMMIT_MSG`
|
||||
echo " <td>$MSG</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
if [ $MR_TRIG -eq 1 ]
|
||||
then
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-log-out\"></span> Source Branch</td>" >> ./build_results.html
|
||||
echo " <td>$SOURCE_BRANCH</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-tag\"></span> Source Commit ID</td>" >> ./build_results.html
|
||||
echo " <td>$SOURCE_COMMIT_ID</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
if [ -e .git/CI_COMMIT_MSG ]
|
||||
then
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-comment\"></span> Source Commit Message</td>" >> ./build_results.html
|
||||
MSG=`cat .git/CI_COMMIT_MSG`
|
||||
echo " <td>$MSG</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
fi
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-log-in\"></span> Target Branch</td>" >> ./build_results.html
|
||||
echo " <td>$TARGET_BRANCH</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-tag\"></span> Target Commit ID</td>" >> ./build_results.html
|
||||
echo " <td>$TARGET_COMMIT_ID</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
fi
|
||||
echo " </table>" >> ./build_results.html
|
||||
echo " <h2>Build Summary</h2>" >> ./build_results.html
|
||||
|
||||
echo " <h3>OAI Coding / Formatting Guidelines Check</h3>" >> ./build_results.html
|
||||
if [ -f ./header-files-w-incorrect-define.txt ]
|
||||
then
|
||||
NB_FILES_IN_ERROR=`wc -l ./header-files-w-incorrect-define.txt | sed -e "s@ .*@@"`
|
||||
if [ $NB_FILES_IN_ERROR -eq 0 ]
|
||||
then
|
||||
echo " <div class=\"alert alert-success\">" >> ./build_results.html
|
||||
if [ $MR_TRIG -eq 1 ]; then echo " <strong>No Issue for CIRCULAR DEPENDENCY PROTECTION in modified files</strong>" >> ./build_results.html; fi
|
||||
if [ $PU_TRIG -eq 1 ]; then echo " <strong>No Issue for CIRCULAR DEPENDENCY PROTECTION in the whole repository</strong>" >> ./build_results.html; fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
else
|
||||
echo " <div class=\"alert alert-warning\">" >> ./build_results.html
|
||||
if [ $MR_TRIG -eq 1 ]; then echo " <strong>${NB_FILES_IN_ERROR} modified files MAY NOT HAVE CIRCULAR DEPENDENCY PROTECTION</strong>" >> ./build_results.html; fi
|
||||
if [ $PU_TRIG -eq 1 ]; then echo " <strong>${NB_FILES_IN_ERROR} files in repository MAY NOT HAVE CIRCULAR DEPENDENCY PROTECTION in the whole repository</strong>" >> ./build_results.html; fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <button data-toggle=\"collapse\" data-target=\"#oai-circular-details\">More details on circular dependency protection check</button>" >> ./build_results.html
|
||||
echo " <div id=\"oai-circular-details\" class=\"collapse\">" >> ./build_results.html
|
||||
echo " <table border = 1>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <th bgcolor = \"lightcyan\" >Potential Issue</th>" >> ./build_results.html
|
||||
echo " <th bgcolor = \"lightcyan\" >Impacted File</th>" >> ./build_results.html
|
||||
echo " <th bgcolor = \"lightcyan\" >Incorrect Macro</th>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
awk '{if($0 ~/error in/){print " <tr><td>error in declaration</td><td>"$4"</td><td>"$5"</td></tr>"};if($0 ~/files with same/){print " <tr><td>files with same #define</td><td>"$5"</td><td>"$6"</td></tr>"}}' ./header-files-w-incorrect-define.txt >> ./build_results.html
|
||||
echo " </table>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
if [ -f ./files-w-gnu-gpl-license-banner.txt ]
|
||||
then
|
||||
NB_FILES_IN_ERROR=`wc -l ./files-w-gnu-gpl-license-banner.txt | sed -e "s@ .*@@"`
|
||||
if [ $NB_FILES_IN_ERROR -ne 0 ]
|
||||
then
|
||||
echo " <div class=\"alert alert-danger\">" >> ./build_results.html
|
||||
if [ $MR_TRIG -eq 1 ]; then echo " <strong>${NB_FILES_IN_ERROR} modified files HAVE a GNU GPL license banner</strong>" >> ./build_results.html; fi
|
||||
if [ $PU_TRIG -eq 1 ]; then echo " <strong>${NB_FILES_IN_ERROR} files in repository HAVE a GNU GPL license banner</strong>" >> ./build_results.html; fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <button data-toggle=\"collapse\" data-target=\"#oai-license-gpl\">More details on GNU GPL license banner issue</button>" >> ./build_results.html
|
||||
echo " <div id=\"oai-license-gpl\" class=\"collapse\">" >> ./build_results.html
|
||||
echo " <table border = 1>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <th bgcolor = \"lightcyan\" >Filename</th>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
awk '{print " <tr><td>"$1"</td></tr>"}' ./files-w-gnu-gpl-license-banner.txt >> ./build_results.html
|
||||
echo " </table>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
if [ -f ./files-w-suspect-banner.txt ]
|
||||
then
|
||||
NB_FILES_IN_ERROR=`wc -l ./files-w-suspect-banner.txt | sed -e "s@ .*@@"`
|
||||
if [ $NB_FILES_IN_ERROR -ne 0 ]
|
||||
then
|
||||
echo " <div class=\"alert alert-warning\">" >> ./build_results.html
|
||||
if [ $MR_TRIG -eq 1 ]; then echo " <strong>${NB_FILES_IN_ERROR} modified files HAVE a suspect license banner</strong>" >> ./build_results.html; fi
|
||||
if [ $PU_TRIG -eq 1 ]; then echo " <strong>${NB_FILES_IN_ERROR} files in repository HAVE a suspect license banner</strong>" >> ./build_results.html; fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <button data-toggle=\"collapse\" data-target=\"#oai-license-suspect\">More details on suspect banner files</button>" >> ./build_results.html
|
||||
echo " <div id=\"oai-license-suspect\" class=\"collapse\">" >> ./build_results.html
|
||||
echo " <table border = 1>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <th bgcolor = \"lightcyan\" >Filename</th>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
awk '{print " <tr><td>"$1"</td></tr>"}' ././files-w-suspect-banner.txt >> ./build_results.html
|
||||
echo " </table>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
|
||||
echo " <h2>Ubuntu 16.04 LTS -- Summary</h2>" >> ./build_results.html
|
||||
|
||||
if [ -f archives/gnb_usrp/nr-softmodem.txt ]
|
||||
then
|
||||
summary_table_header "OAI Build: 5G NR gNB -- USRP option" ./archives/gnb_usrp
|
||||
summary_table_row "5G NR SoftModem" ./archives/gnb_usrp/nr-softmodem.txt "Built target nr-softmodem" ./gnb_usrp_row1.html
|
||||
summary_table_row "Coding" ./archives/gnb_usrp/coding.txt "Built target coding" ./gnb_usrp_row2.html
|
||||
summary_table_row "OAI USRP device if" ./archives/gnb_usrp/oai_usrpdevif.txt "Built target oai_usrpdevif" ./gnb_usrp_row3.html
|
||||
summary_table_row "OAI ETHERNET transport" ./archives/gnb_usrp/oai_eth_transpro.txt "Built target oai_eth_transpro" ./gnb_usrp_row4.html
|
||||
summary_table_row "Parameters Lib Config" ./archives/gnb_usrp/params_libconfig.txt "Built target params_libconfig" ./gnb_usrp_row6.html
|
||||
summary_table_footer
|
||||
fi
|
||||
|
||||
if [ -f archives/nr_ue_usrp/nr-uesoftmodem.txt ]
|
||||
then
|
||||
summary_table_header "OAI Build: 5G NR UE -- USRP option" ./archives/nr_ue_usrp
|
||||
summary_table_row "5G NR UE SoftModem" ./archives/nr_ue_usrp/nr-uesoftmodem.txt "Built target nr-uesoftmodem" ./nr_ue_usrp_row1.html
|
||||
summary_table_row "Coding" ./archives/nr_ue_usrp/coding.txt "Built target coding" ./nr_ue_usrp_row2.html
|
||||
summary_table_row "OAI USRP device if" ./archives/nr_ue_usrp/oai_usrpdevif.txt "Built target oai_usrpdevif" ./nr_ue_usrp_row3.html
|
||||
summary_table_row "OAI ETHERNET transport" ./archives/nr_ue_usrp/oai_eth_transpro.txt "Built target oai_eth_transpro" ./nr_ue_usrp_row4.html
|
||||
summary_table_row "Parameters Lib Config" ./archives/nr_ue_usrp/params_libconfig.txt "Built target params_libconfig" ./nr_ue_usrp_row6.html
|
||||
summary_table_footer
|
||||
fi
|
||||
|
||||
if [ -e ./archives/red_hat ]
|
||||
then
|
||||
echo " <h2>Red Hat Enterprise Linux Server release 7.6) -- Summary</h2>" >> ./build_results.html
|
||||
|
||||
summary_table_header "OAI Build: 4G LTE eNB -- USRP option (RHEL)" ./archives/red_hat
|
||||
summary_table_row "LTE SoftModem" ./archives/red_hat/lte-softmodem.txt "Built target lte-softmodem" ./enb_usrp_rh_row1.html
|
||||
summary_table_row "Coding" ./archives/red_hat/coding.txt "Built target coding" ./enb_usrp_rh_row2.html
|
||||
summary_table_row "OAI USRP device if" ./archives/red_hat/oai_usrpdevif.txt "Built target oai_usrpdevif" ./enb_usrp_rh_row3.html
|
||||
summary_table_row "Parameters Lib Config" ./archives/red_hat/params_libconfig.txt "Built target params_libconfig" ./enb_usrp_rh_row4.html
|
||||
summary_table_footer
|
||||
fi
|
||||
|
||||
echo " <h3>Details</h3>" >> ./build_results.html
|
||||
echo " <button data-toggle=\"collapse\" data-target=\"#oai-compilation-details\">Details for Compilation Errors and Warnings </button>" >> ./build_results.html
|
||||
echo " <div id=\"oai-compilation-details\" class=\"collapse\">" >> ./build_results.html
|
||||
|
||||
if [ -f ./enb_eth_row1.html ] || [ -f ./enb_eth_row2.html ] || [ -f ./enb_eth_row3.html ] || [ -f ./enb_eth_row4.html ] || [ -f ./enb_eth_row5.html ] || [ -f ./enb_eth_row6.html ] || [ -f ./enb_eth_row7.html ]
|
||||
then
|
||||
for DETAILS_TABLE in `ls ./enb_eth_row*.html`
|
||||
do
|
||||
cat $DETAILS_TABLE >> ./build_results.html
|
||||
done
|
||||
fi
|
||||
if [ -f ./ue_eth_row1.html ] || [ -f ./ue_eth_row2.html ] || [ -f ./ue_eth_row3.html ] || [ -f ./ue_eth_row4.html ] || [ -f ./ue_eth_row5.html ] || [ -f ./ue_eth_row6.html ] || [ -f ./ue_eth_row7.html ] || [ -f ./ue_eth_row8.html ] || [ -f ./ue_eth_row9.html ] || [ -f ./ue_eth_row9a.html ] || [ -f ./ue_eth_row9b.html ]
|
||||
then
|
||||
for DETAILS_TABLE in `ls ./ue_eth_row*.html`
|
||||
do
|
||||
cat $DETAILS_TABLE >> ./build_results.html
|
||||
done
|
||||
fi
|
||||
if [ -f ./gnb_usrp_row1.html ] || [ -f ./gnb_usrp_row2.html ] || [ -f ./gnb_usrp_row3.html ] || [ -f ./gnb_usrp_row4.html ]
|
||||
then
|
||||
for DETAILS_TABLE in `ls ./gnb_usrp_row*.html`
|
||||
do
|
||||
cat $DETAILS_TABLE >> ./build_results.html
|
||||
done
|
||||
fi
|
||||
if [ -f ./nr_ue_usrp_row1.html ] || [ -f ./nr_ue_usrp_row2.html ] || [ -f ./nr_ue_usrp_row3.html ] || [ -f ./nr_ue_usrp_row4.html ]
|
||||
then
|
||||
for DETAILS_TABLE in `ls ./nr_ue_usrp_row*.html`
|
||||
do
|
||||
cat $DETAILS_TABLE >> ./build_results.html
|
||||
done
|
||||
fi
|
||||
rm -f ./*_row*.html
|
||||
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <p></p>" >> ./build_results.html
|
||||
echo " <div class=\"well well-lg\">End of Build Report -- Copyright <span class=\"glyphicon glyphicon-copyright-mark\"></span> 2018 <a href=\"http://www.openairinterface.org/\">OpenAirInterface</a>. All Rights Reserved.</div>" >> ./build_results.html
|
||||
echo "</div></body>" >> ./build_results.html
|
||||
echo "</html>" >> ./build_results.html
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,205 +0,0 @@
|
||||
#!/bin/bash
|
||||
#/*
|
||||
# * 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
|
||||
# */
|
||||
|
||||
function wait_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo " Requirements:"
|
||||
echo " -- uvtool uvtool-libvirt apt-cacher"
|
||||
echo " -- $VM_OSREL image already synced"
|
||||
echo " Default:"
|
||||
echo " -- eNB with USRP"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo " oai-ci-vm-tool wait [OPTIONS]"
|
||||
echo ""
|
||||
command_options_usage
|
||||
}
|
||||
|
||||
function wait_on_vm_build {
|
||||
echo "############################################################"
|
||||
echo "OAI CI VM script"
|
||||
echo "############################################################"
|
||||
|
||||
echo "VM_NAME = $VM_NAME"
|
||||
echo "VM_CMD_FILE = $VM_CMDS"
|
||||
echo "JENKINS_WKSP = $JENKINS_WKSP"
|
||||
echo "ARCHIVES_LOC = $ARCHIVES_LOC"
|
||||
echo "BUILD_OPTIONS = $BUILD_OPTIONS"
|
||||
|
||||
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]] || [[ "$VM_NAME" == *"-basic-sim"* ]] || [[ "$VM_NAME" == *"-flexran-rtc"* ]] || [[ "$VM_NAME" == *"-rf-sim"* ]] || [[ "$VM_NAME" == *"-ethernet"* ]] || [[ "$VM_NAME" == *"rf5g-sim"* ]] || [[ "$VM_NAME" == *"gnb-usrp"* ]] || [[ "$VM_NAME" == *"nr-ue-usrp"* ]]
|
||||
then
|
||||
echo "This VM type is no longer supported in the pipeline framework"
|
||||
return
|
||||
fi
|
||||
|
||||
IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME`
|
||||
|
||||
if [ $IS_VM_ALIVE -eq 0 ]
|
||||
then
|
||||
echo "############################################################"
|
||||
echo "You should have created the VM before doing anything"
|
||||
echo "############################################################"
|
||||
STATUS=1
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Waiting for VM to be started"
|
||||
uvt-kvm wait $VM_NAME --insecure
|
||||
|
||||
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
|
||||
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
|
||||
|
||||
echo "############################################################"
|
||||
echo "Waiting build process to end on VM ($VM_NAME)"
|
||||
echo "############################################################"
|
||||
# Since the last VM was cppcheck and is removed
|
||||
# we are going too fast in wait and the build_oai is not yet started
|
||||
sleep 120
|
||||
|
||||
if [[ "$VM_NAME" == *"-cppcheck"* ]]
|
||||
then
|
||||
echo "echo \"ps -aux | grep cppcheck \"" >> $VM_CMDS
|
||||
echo "while [ \$(ps -aux | grep --color=never cppcheck | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS
|
||||
else
|
||||
echo "echo \"ps -aux | grep build \"" >> $VM_CMDS
|
||||
echo "while [ \$(ps -aux | grep --color=never build_oai | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS
|
||||
fi
|
||||
echo "echo \"df -h\"" >> $VM_CMDS
|
||||
echo "df -h" >> $VM_CMDS
|
||||
|
||||
ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS
|
||||
rm -f $VM_CMDS
|
||||
}
|
||||
|
||||
function check_on_vm_build {
|
||||
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]] || [[ "$VM_NAME" == *"-basic-sim"* ]] || [[ "$VM_NAME" == *"-flexran-rtc"* ]] || [[ "$VM_NAME" == *"-rf-sim"* ]] || [[ "$VM_NAME" == *"-ethernet"* ]] || [[ "$VM_NAME" == *"rf5g-sim"* ]] || [[ "$VM_NAME" == *"gnb-usrp"* ]] || [[ "$VM_NAME" == *"nr-ue-usrp"* ]]
|
||||
then
|
||||
echo "This VM type is no longer supported in the pipeline framework"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "############################################################"
|
||||
echo "Creating a tmp folder to store results and artifacts"
|
||||
echo "############################################################"
|
||||
if [ ! -d $JENKINS_WKSP/archives ]
|
||||
then
|
||||
mkdir $JENKINS_WKSP/archives
|
||||
fi
|
||||
|
||||
if [ ! -d $ARCHIVES_LOC ]
|
||||
then
|
||||
mkdir $ARCHIVES_LOC
|
||||
fi
|
||||
|
||||
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.txt $ARCHIVES_LOC
|
||||
if [[ "$VM_NAME" == *"-cppcheck"* ]]
|
||||
then
|
||||
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.xml $ARCHIVES_LOC
|
||||
fi
|
||||
|
||||
if [ $KEEP_VM_ALIVE -eq 0 ]
|
||||
then
|
||||
if [[ "$VM_NAME" == *"-enb-ethernet"* ]] || [[ "$VM_NAME" == *"-ue-ethernet"* ]]
|
||||
then
|
||||
echo "Hack to not destroy in current pipeline"
|
||||
else
|
||||
echo "############################################################"
|
||||
echo "Destroying VM"
|
||||
echo "############################################################"
|
||||
uvt-kvm destroy $VM_NAME
|
||||
ssh-keygen -R $VM_IP_ADDR
|
||||
fi
|
||||
fi
|
||||
rm -f $VM_CMDS
|
||||
|
||||
echo "############################################################"
|
||||
echo "Checking build status"
|
||||
echo "############################################################"
|
||||
|
||||
if [[ "$VM_NAME" == *"-cppcheck"* ]]
|
||||
then
|
||||
LOG_FILES=`ls $ARCHIVES_LOC/*.txt $ARCHIVES_LOC/*.xml`
|
||||
else
|
||||
LOG_FILES=`ls $ARCHIVES_LOC/*.txt`
|
||||
fi
|
||||
echo "LOG_FILES=$LOG_FILES"
|
||||
echo "expecting NB_PATTERN_FILES=$NB_PATTERN_FILES"
|
||||
STATUS=0
|
||||
NB_FOUND_FILES=0
|
||||
|
||||
for FULLFILE in $LOG_FILES
|
||||
do
|
||||
if [[ $FULLFILE == *"$LOG_PATTERN"* ]]
|
||||
then
|
||||
filename=$(basename -- "$FULLFILE")
|
||||
if [ "$LOG_PATTERN" == ".txt" ]
|
||||
then
|
||||
PASS_PATTERN=`echo $filename | sed -e "s#$LOG_PATTERN##"`
|
||||
fi
|
||||
if [ "$LOG_PATTERN" == "cppcheck.xml" ]
|
||||
then
|
||||
PASS_PATTERN="results version"
|
||||
LOCAL_STAT=`egrep -c "$PASS_PATTERN" $FULLFILE`
|
||||
else
|
||||
LOCAL_STAT=`egrep -c "Built target $PASS_PATTERN" $FULLFILE`
|
||||
fi
|
||||
if [ $LOCAL_STAT -eq 0 ]; then
|
||||
echo "WARNING: file $filename does not contain pass pattern"
|
||||
else
|
||||
NB_FOUND_FILES=$((NB_FOUND_FILES + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]
|
||||
then
|
||||
echo "Expecting $NB_PATTERN_FILES log files and found $NB_FOUND_FILES"
|
||||
STATUS=-1
|
||||
fi
|
||||
|
||||
# If we were building the FlexRan Controller, flag-touch for basic-simulator to continue
|
||||
#if [[ "$VM_NAME" == *"-flexran-rtc"* ]]
|
||||
#then
|
||||
# if [[ $STATUS -eq 0 ]]
|
||||
# then
|
||||
# touch $JENKINS_WKSP/flexran/flexran_build_complete.txt
|
||||
# fi
|
||||
#fi
|
||||
|
||||
if [[ "$VM_NAME" == *"-cppcheck"* ]]
|
||||
then
|
||||
echo "COMMAND: cppcheck $BUILD_OPTIONS . 2> cppcheck.xml" > $ARCHIVES_LOC/build_final_status.log
|
||||
elif [[ "$VM_NAME" == *"-flexran-rtc"* ]]
|
||||
then
|
||||
echo "COMMAND: $BUILD_OPTIONS" > $ARCHIVES_LOC/build_final_status.log
|
||||
else
|
||||
echo "COMMAND: build_oai -I $BUILD_OPTIONS" > $ARCHIVES_LOC/build_final_status.log
|
||||
fi
|
||||
if [[ $STATUS -eq 0 ]]
|
||||
then
|
||||
echo "BUILD_OK" >> $ARCHIVES_LOC/build_final_status.log
|
||||
else
|
||||
echo "BUILD_KO" >> $ARCHIVES_LOC/build_final_status.log
|
||||
fi
|
||||
}
|
||||
124
ci-scripts/xml_files/container_5g_rfsim_2x2.xml
Normal file
124
ci-scripts/xml_files/container_5g_rfsim_2x2.xml
Normal file
@@ -0,0 +1,124 @@
|
||||
<!--
|
||||
|
||||
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
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>rfsim-5gnr-tdd-2x2</htmlTabRef>
|
||||
<htmlTabName>Monolithic SA TDD 2x2 gNB</htmlTabName>
|
||||
<htmlTabIcon>wrench</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
111111
|
||||
100001
|
||||
000000
|
||||
000001
|
||||
000002
|
||||
000003
|
||||
020001
|
||||
020002
|
||||
030001
|
||||
030002
|
||||
100001
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="111111">
|
||||
<class>Pull_Local_Registry</class>
|
||||
<desc>Pull Images from Local Registry</desc>
|
||||
<test_svr_id>0</test_svr_id>
|
||||
<images_to_pull>oai-gnb oai-nr-ue</images_to_pull>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000000">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy MySql Database</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_2x2</yaml_path>
|
||||
<services>mysql</services>
|
||||
<nb_healthy>1</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000001">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G CoreNetwork</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_2x2</yaml_path>
|
||||
<services>oai-nrf oai-amf oai-smf oai-spgwu oai-ext-dn</services>
|
||||
<nb_healthy>6</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000002">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G gNB RF sim SA</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_2x2</yaml_path>
|
||||
<services>oai-gnb</services>
|
||||
<nb_healthy>7</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000003">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G NR-UE RF sim SA</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_2x2</yaml_path>
|
||||
<services>oai-nr-ue</services>
|
||||
<nb_healthy>8</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020001">
|
||||
<class>PingFromContainer</class>
|
||||
<desc>Ping ext-dn from NR-UE</desc>
|
||||
<container_name>rfsim5g-oai-nr-ue</container_name>
|
||||
<options>-I oaitun_ue1 -c 20 192.168.72.135</options>
|
||||
<loss_threshold>5</loss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020002">
|
||||
<class>PingFromContainer</class>
|
||||
<desc>Ping NR-UE from ext-dn</desc>
|
||||
<container_name>rfsim5g-oai-ext-dn</container_name>
|
||||
<options>-c 20 12.1.1.2</options>
|
||||
<loss_threshold>5</loss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030001">
|
||||
<class>IperfFromContainer</class>
|
||||
<desc>Iperf UDP Downlink</desc>
|
||||
<server_container_name>rfsim5g-oai-nr-ue</server_container_name>
|
||||
<client_container_name>rfsim5g-oai-ext-dn</client_container_name>
|
||||
<server_options>-B 12.1.1.2 -u -i 1 -s</server_options>
|
||||
<client_options>-c 12.1.1.2 -u -i 1 -t 10 -b 3M</client_options>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030002">
|
||||
<class>IperfFromContainer</class>
|
||||
<desc>Iperf UDP Uplink</desc>
|
||||
<server_container_name>rfsim5g-oai-ext-dn</server_container_name>
|
||||
<client_container_name>rfsim5g-oai-nr-ue</client_container_name>
|
||||
<server_options>-u -i 1 -s</server_options>
|
||||
<client_options>-B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 10 -b 1M</client_options>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100001">
|
||||
<class>UndeployGenObject</class>
|
||||
<desc>Undeploy all OAI 5G stack</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_2x2</yaml_path>
|
||||
<d_retx_th>1,0,0,0</d_retx_th>
|
||||
<u_retx_th>1,0,0,0</u_retx_th>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
45
ci-scripts/xml_files/container_5g_rfsim_2x2_down.xml
Normal file
45
ci-scripts/xml_files/container_5g_rfsim_2x2_down.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<!--
|
||||
|
||||
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
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>rfsim-5gnr-2x2-down</htmlTabRef>
|
||||
<htmlTabName>CleanUp SA Monolithic TDD 2x2 gNB</htmlTabName>
|
||||
<htmlTabIcon>trash</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
100002
|
||||
222222
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="100002">
|
||||
<class>UndeployGenObject</class>
|
||||
<desc>Undeploy all OAI 5G stack</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_2x2</yaml_path>
|
||||
</testCase>
|
||||
|
||||
<testCase id="222222">
|
||||
<class>Clean_Test_Server_Images</class>
|
||||
<desc>Clean Test Images on Test Server</desc>
|
||||
<test_svr_id>0</test_svr_id>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
124
ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml
Normal file
124
ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml
Normal file
@@ -0,0 +1,124 @@
|
||||
<!--
|
||||
|
||||
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
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>rfsim-5gnr-tdd-u0-25prb</htmlTabRef>
|
||||
<htmlTabName>Monolithic SA TDD u0 25PRB gNB</htmlTabName>
|
||||
<htmlTabIcon>wrench</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
111111
|
||||
100001
|
||||
000000
|
||||
000001
|
||||
000002
|
||||
000003
|
||||
020001
|
||||
020002
|
||||
030001
|
||||
030002
|
||||
100001
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="111111">
|
||||
<class>Pull_Local_Registry</class>
|
||||
<desc>Pull Images from Local Registry</desc>
|
||||
<test_svr_id>0</test_svr_id>
|
||||
<images_to_pull>oai-gnb oai-nr-ue</images_to_pull>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000000">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy MySql Database</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_u0_25prb</yaml_path>
|
||||
<services>mysql</services>
|
||||
<nb_healthy>1</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000001">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G CoreNetwork</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_u0_25prb</yaml_path>
|
||||
<services>oai-nrf oai-amf oai-smf oai-spgwu oai-ext-dn</services>
|
||||
<nb_healthy>6</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000002">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G gNB RF sim SA</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_u0_25prb</yaml_path>
|
||||
<services>oai-gnb</services>
|
||||
<nb_healthy>7</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000003">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G NR-UE RF sim SA</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_u0_25prb</yaml_path>
|
||||
<services>oai-nr-ue</services>
|
||||
<nb_healthy>8</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020001">
|
||||
<class>PingFromContainer</class>
|
||||
<desc>Ping ext-dn from NR-UE</desc>
|
||||
<container_name>rfsim5g-oai-nr-ue</container_name>
|
||||
<options>-I oaitun_ue1 -c 20 192.168.72.135</options>
|
||||
<loss_threshold>5</loss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020002">
|
||||
<class>PingFromContainer</class>
|
||||
<desc>Ping NR-UE from ext-dn</desc>
|
||||
<container_name>rfsim5g-oai-ext-dn</container_name>
|
||||
<options>-c 20 12.1.1.2</options>
|
||||
<loss_threshold>5</loss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030001">
|
||||
<class>IperfFromContainer</class>
|
||||
<desc>Iperf UDP Downlink</desc>
|
||||
<server_container_name>rfsim5g-oai-nr-ue</server_container_name>
|
||||
<client_container_name>rfsim5g-oai-ext-dn</client_container_name>
|
||||
<server_options>-B 12.1.1.2 -u -i 1 -s</server_options>
|
||||
<client_options>-c 12.1.1.2 -u -i 1 -t 10 -b 3M</client_options>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030002">
|
||||
<class>IperfFromContainer</class>
|
||||
<desc>Iperf UDP Uplink</desc>
|
||||
<server_container_name>rfsim5g-oai-ext-dn</server_container_name>
|
||||
<client_container_name>rfsim5g-oai-nr-ue</client_container_name>
|
||||
<server_options>-u -i 1 -s</server_options>
|
||||
<client_options>-B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 10 -b 1M</client_options>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100001">
|
||||
<class>UndeployGenObject</class>
|
||||
<desc>Undeploy all OAI 5G stack</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_u0_25prb</yaml_path>
|
||||
<d_retx_th>1,0,0,0</d_retx_th>
|
||||
<u_retx_th>1,0,0,0</u_retx_th>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
45
ci-scripts/xml_files/container_5g_rfsim_u0_25prb_down.xml
Normal file
45
ci-scripts/xml_files/container_5g_rfsim_u0_25prb_down.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<!--
|
||||
|
||||
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
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>rfsim-5gnr-u0-25prb-down</htmlTabRef>
|
||||
<htmlTabName>CleanUp SA Monolithic TDD u0 25PRB gNB</htmlTabName>
|
||||
<htmlTabIcon>trash</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
100002
|
||||
222222
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="100002">
|
||||
<class>UndeployGenObject</class>
|
||||
<desc>Undeploy all OAI 5G stack</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_u0_25prb</yaml_path>
|
||||
</testCase>
|
||||
|
||||
<testCase id="222222">
|
||||
<class>Clean_Test_Server_Images</class>
|
||||
<desc>Clean Test Images on Test Server</desc>
|
||||
<test_svr_id>0</test_svr_id>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
@@ -54,13 +54,14 @@
|
||||
<testCase id="040000">
|
||||
<class>Initialize_eNB</class>
|
||||
<desc>Initialize gNB</desc>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf --sa --usrp-tx-thread-config 1 --tune-offset 30000000 --thread-pool 1,3,5,7,9,11,13,15 --gNBs.[0].min_rxtxtime 5 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf --gNBs.[0].min_rxtxtime 5 --sa --usrp-tx-thread-config 1 --tune-offset 30000000 --thread-pool 1,3,5,7,9,11,13,15 --gNBs.[0].min_rxtxtime 5 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
<air_interface>nr</air_interface>
|
||||
<eNB_Trace>yes</eNB_Trace>
|
||||
<eNB_Stats>yes</eNB_Stats>
|
||||
<USRP_IPAddress>172.21.19.14</USRP_IPAddress>
|
||||
<cmd_prefix>numactl --cpunodebind=netdev:ens2f0np0 --membind=netdev:ens2f0np0</cmd_prefix>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000001">
|
||||
|
||||
301
ci-scripts/yaml_files/5g_rfsimulator_2x2/docker-compose.yaml
Normal file
301
ci-scripts/yaml_files/5g_rfsimulator_2x2/docker-compose.yaml
Normal file
@@ -0,0 +1,301 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
oai-nrf:
|
||||
container_name: "rfsim5g-oai-nrf"
|
||||
image: oai-nrf:august-dev
|
||||
environment:
|
||||
- NRF_INTERFACE_NAME_FOR_SBI=eth0
|
||||
- NRF_INTERFACE_PORT_FOR_SBI=80
|
||||
- NRF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
|
||||
- NRF_API_VERSION=v1
|
||||
- INSTANCE=0
|
||||
- PID_DIRECTORY=/var/run
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.130
|
||||
volumes:
|
||||
- ../5g_rfsimulator/nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
mysql:
|
||||
container_name: "rfsim5g-mysql"
|
||||
image: mysql:5.7
|
||||
volumes:
|
||||
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
|
||||
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- MYSQL_DATABASE=oai_db
|
||||
- MYSQL_USER=test
|
||||
- MYSQL_PASSWORD=test
|
||||
- MYSQL_ROOT_PASSWORD=linux
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.131
|
||||
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oai-amf:august-dev
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
- INSTANCE=0
|
||||
- PID_DIRECTORY=/var/run
|
||||
- MCC=208
|
||||
- MNC=99
|
||||
- REGION_ID=128
|
||||
- AMF_SET_ID=1
|
||||
- SERVED_GUAMI_MCC_0=208
|
||||
- SERVED_GUAMI_MNC_0=99
|
||||
- SERVED_GUAMI_REGION_ID_0=128
|
||||
- SERVED_GUAMI_AMF_SET_ID_0=1
|
||||
- SERVED_GUAMI_MCC_1=460
|
||||
- SERVED_GUAMI_MNC_1=11
|
||||
- SERVED_GUAMI_REGION_ID_1=10
|
||||
- SERVED_GUAMI_AMF_SET_ID_1=1
|
||||
- PLMN_SUPPORT_MCC=208
|
||||
- PLMN_SUPPORT_MNC=99
|
||||
- PLMN_SUPPORT_TAC=0x0001
|
||||
- SST_0=1
|
||||
- SD_0=0xffffff
|
||||
- SST_1=1
|
||||
- SD_1=1
|
||||
- AMF_INTERFACE_NAME_FOR_NGAP=eth0
|
||||
- AMF_INTERFACE_NAME_FOR_N11=eth0
|
||||
- SMF_INSTANCE_ID_0=1
|
||||
- SMF_FQDN_0=oai-smf
|
||||
- SMF_IPV4_ADDR_0=0.0.0.0
|
||||
- SMF_HTTP_VERSION_0=v1
|
||||
- SELECTED_0=true
|
||||
- SMF_INSTANCE_ID_1=2
|
||||
- SMF_FQDN_1=oai-smf
|
||||
- SMF_IPV4_ADDR_1=0.0.0.0
|
||||
- SMF_HTTP_VERSION_1=v1
|
||||
- SELECTED_1=false
|
||||
- MYSQL_SERVER=192.168.71.131
|
||||
- MYSQL_USER=root
|
||||
- MYSQL_PASS=linux
|
||||
- MYSQL_DB=oai_db
|
||||
- OPERATOR_KEY=c42449363bbad02b66d16bc975d77cc1
|
||||
- NRF_IPV4_ADDRESS=192.168.71.130
|
||||
- NRF_PORT=80
|
||||
- NF_REGISTRATION=yes
|
||||
- SMF_SELECTION=yes
|
||||
- USE_FQDN_DNS=yes
|
||||
- NRF_API_VERSION=v1
|
||||
- NRF_FQDN=oai-nrf
|
||||
- EXTERNAL_AUSF=no
|
||||
- AUSF_IPV4_ADDRESS=0.0.0.0
|
||||
- AUSF_PORT=80
|
||||
- AUSF_API_VERSION=v1
|
||||
- AUSF_FQDN=localhost
|
||||
depends_on:
|
||||
- oai-nrf
|
||||
- mysql
|
||||
volumes:
|
||||
- ../5g_rfsimulator/amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh"
|
||||
interval: 10s
|
||||
timeout: 15s
|
||||
retries: 5
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.132
|
||||
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oai-smf:august-dev
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- INSTANCE=0
|
||||
- PID_DIRECTORY=/var/run
|
||||
- SMF_INTERFACE_NAME_FOR_N4=eth0
|
||||
- SMF_INTERFACE_NAME_FOR_SBI=eth0
|
||||
- SMF_INTERFACE_PORT_FOR_SBI=80
|
||||
- SMF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
|
||||
- SMF_API_VERSION=v1
|
||||
- DEFAULT_DNS_IPV4_ADDRESS=172.21.3.100
|
||||
- DEFAULT_DNS_SEC_IPV4_ADDRESS=4.4.4.4
|
||||
- AMF_IPV4_ADDRESS=0.0.0.0
|
||||
- AMF_PORT=80
|
||||
- AMF_API_VERSION=v1
|
||||
- AMF_FQDN=oai-amf
|
||||
- UDM_IPV4_ADDRESS=127.0.0.1
|
||||
- UDM_PORT=80
|
||||
- UDM_API_VERSION=v1
|
||||
- UDM_FQDN=localhost
|
||||
- UPF_IPV4_ADDRESS=192.168.71.134
|
||||
- UPF_FQDN_0=oai-spgwu
|
||||
- NRF_IPV4_ADDRESS=192.168.71.130
|
||||
- NRF_PORT=80
|
||||
- NRF_API_VERSION=v1
|
||||
- NRF_FQDN=oai-nrf
|
||||
- REGISTER_NRF=yes
|
||||
- DISCOVER_UPF=yes
|
||||
- USE_FQDN_DNS=yes
|
||||
- DNN_NI0=oai
|
||||
- TYPE0=IPv4
|
||||
- DNN_RANGE0=12.1.1.2 - 12.1.1.127
|
||||
- NSSAI_SST0=1
|
||||
- NSSAI_SD0=0xFFFFFF
|
||||
- SESSION_AMBR_UL0=200Mbps
|
||||
- SESSION_AMBR_DL0=400Mbps
|
||||
- DNN_NI2=oai.ipv4
|
||||
depends_on:
|
||||
- oai-nrf
|
||||
- oai-amf
|
||||
volumes:
|
||||
- ../5g_rfsimulator/smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.133
|
||||
|
||||
oai-spgwu:
|
||||
container_name: "rfsim5g-oai-spgwu"
|
||||
image: oai-spgwu-tiny:august-dev
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- PID_DIRECTORY=/var/run
|
||||
- SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP=eth0
|
||||
- SGW_INTERFACE_NAME_FOR_SX=eth0
|
||||
- PGW_INTERFACE_NAME_FOR_SGI=eth0
|
||||
- NETWORK_UE_NAT_OPTION=yes
|
||||
- NETWORK_UE_IP=12.1.1.0/24
|
||||
- SPGWC0_IP_ADDRESS=192.168.71.133
|
||||
- BYPASS_UL_PFCP_RULES=no
|
||||
- MCC=208
|
||||
- MNC=99
|
||||
- MNC03=099
|
||||
- TAC=1
|
||||
- GTP_EXTENSION_HEADER_PRESENT=yes
|
||||
- GW_ID=1
|
||||
- REALM=openairinterface.org
|
||||
- ENABLE_5G_FEATURES=yes
|
||||
- REGISTER_NRF=yes
|
||||
- USE_FQDN_NRF=yes
|
||||
- UPF_FQDN_5G=oai-spgwu
|
||||
- NRF_IPV4_ADDRESS=192.168.71.130
|
||||
- NRF_PORT=80
|
||||
- NRF_API_VERSION=v1
|
||||
- NRF_FQDN=oai-nrf
|
||||
- NSSAI_SST_0=1
|
||||
- NSSAI_SD_0=0xffffff
|
||||
- DNN_0=oai
|
||||
depends_on:
|
||||
- oai-nrf
|
||||
- oai-smf
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_ADMIN
|
||||
cap_drop:
|
||||
- ALL
|
||||
privileged: true
|
||||
volumes:
|
||||
- ../5g_rfsimulator/spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/openair-spgwu-tiny/bin/spgwu-healthcheck.sh"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.134
|
||||
traffic_net:
|
||||
ipv4_address: 192.168.72.134
|
||||
|
||||
oai-ext-dn:
|
||||
image: ubuntu:bionic
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-ext-dn
|
||||
entrypoint: /bin/bash -c \
|
||||
"apt update; apt install -y procps iptables iproute2 iperf iputils-ping;"\
|
||||
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
|
||||
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
|
||||
depends_on:
|
||||
- oai-spgwu
|
||||
networks:
|
||||
traffic_net:
|
||||
ipv4_address: 192.168.72.135
|
||||
healthcheck:
|
||||
test: /bin/bash -c "ping -c 2 192.168.72.134"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
oai-gnb:
|
||||
image: oai-gnb:develop
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-gnb
|
||||
environment:
|
||||
RFSIMULATOR: server
|
||||
USE_VOLUMED_CONF: 'yes'
|
||||
USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time
|
||||
depends_on:
|
||||
- oai-ext-dn
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.140
|
||||
volumes:
|
||||
- ../../conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf:/opt/oai-gnb/etc/mounted.conf
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-softmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
oai-nr-ue:
|
||||
image: oai-nr-ue:develop
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-nr-ue
|
||||
environment:
|
||||
RFSIMULATOR: 192.168.71.140
|
||||
FULL_IMSI: '208990100001100'
|
||||
FULL_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
|
||||
OPC: 'C42449363BBAD02B66D16BC975D77CC1'
|
||||
DNN: oai
|
||||
NSSAI_SST: 1
|
||||
USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 106 --numerology 1 --band 78 -C 3319680000 --nokrnmod --ue-nb-ant-tx 2 --ue-nb-ant-rx 2 --uecap_file /opt/oai-nr-ue/etc/uecap.xml --log_config.global_log_options level,nocolor,time
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.150
|
||||
volumes:
|
||||
- ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports2.xml:/opt/oai-nr-ue/etc/uecap.xml
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-uesoftmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
networks:
|
||||
public_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-public-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.71.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-public"
|
||||
traffic_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-traffic-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.72.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-traffic"
|
||||
@@ -0,0 +1,299 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
oai-nrf:
|
||||
container_name: "rfsim5g-oai-nrf"
|
||||
image: oai-nrf:august-dev
|
||||
environment:
|
||||
- NRF_INTERFACE_NAME_FOR_SBI=eth0
|
||||
- NRF_INTERFACE_PORT_FOR_SBI=80
|
||||
- NRF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
|
||||
- NRF_API_VERSION=v1
|
||||
- INSTANCE=0
|
||||
- PID_DIRECTORY=/var/run
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.130
|
||||
volumes:
|
||||
- ../5g_rfsimulator/nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
mysql:
|
||||
container_name: "rfsim5g-mysql"
|
||||
image: mysql:5.7
|
||||
volumes:
|
||||
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
|
||||
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- MYSQL_DATABASE=oai_db
|
||||
- MYSQL_USER=test
|
||||
- MYSQL_PASSWORD=test
|
||||
- MYSQL_ROOT_PASSWORD=linux
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.131
|
||||
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oai-amf:august-dev
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
- INSTANCE=0
|
||||
- PID_DIRECTORY=/var/run
|
||||
- MCC=208
|
||||
- MNC=99
|
||||
- REGION_ID=128
|
||||
- AMF_SET_ID=1
|
||||
- SERVED_GUAMI_MCC_0=208
|
||||
- SERVED_GUAMI_MNC_0=99
|
||||
- SERVED_GUAMI_REGION_ID_0=128
|
||||
- SERVED_GUAMI_AMF_SET_ID_0=1
|
||||
- SERVED_GUAMI_MCC_1=460
|
||||
- SERVED_GUAMI_MNC_1=11
|
||||
- SERVED_GUAMI_REGION_ID_1=10
|
||||
- SERVED_GUAMI_AMF_SET_ID_1=1
|
||||
- PLMN_SUPPORT_MCC=208
|
||||
- PLMN_SUPPORT_MNC=99
|
||||
- PLMN_SUPPORT_TAC=0x0001
|
||||
- SST_0=1
|
||||
- SD_0=0xffffff
|
||||
- SST_1=1
|
||||
- SD_1=1
|
||||
- AMF_INTERFACE_NAME_FOR_NGAP=eth0
|
||||
- AMF_INTERFACE_NAME_FOR_N11=eth0
|
||||
- SMF_INSTANCE_ID_0=1
|
||||
- SMF_FQDN_0=oai-smf
|
||||
- SMF_IPV4_ADDR_0=0.0.0.0
|
||||
- SMF_HTTP_VERSION_0=v1
|
||||
- SELECTED_0=true
|
||||
- SMF_INSTANCE_ID_1=2
|
||||
- SMF_FQDN_1=oai-smf
|
||||
- SMF_IPV4_ADDR_1=0.0.0.0
|
||||
- SMF_HTTP_VERSION_1=v1
|
||||
- SELECTED_1=false
|
||||
- MYSQL_SERVER=192.168.71.131
|
||||
- MYSQL_USER=root
|
||||
- MYSQL_PASS=linux
|
||||
- MYSQL_DB=oai_db
|
||||
- OPERATOR_KEY=c42449363bbad02b66d16bc975d77cc1
|
||||
- NRF_IPV4_ADDRESS=192.168.71.130
|
||||
- NRF_PORT=80
|
||||
- NF_REGISTRATION=yes
|
||||
- SMF_SELECTION=yes
|
||||
- USE_FQDN_DNS=yes
|
||||
- NRF_API_VERSION=v1
|
||||
- NRF_FQDN=oai-nrf
|
||||
- EXTERNAL_AUSF=no
|
||||
- AUSF_IPV4_ADDRESS=0.0.0.0
|
||||
- AUSF_PORT=80
|
||||
- AUSF_API_VERSION=v1
|
||||
- AUSF_FQDN=localhost
|
||||
depends_on:
|
||||
- oai-nrf
|
||||
- mysql
|
||||
volumes:
|
||||
- ../5g_rfsimulator/amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh"
|
||||
interval: 10s
|
||||
timeout: 15s
|
||||
retries: 5
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.132
|
||||
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oai-smf:august-dev
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- INSTANCE=0
|
||||
- PID_DIRECTORY=/var/run
|
||||
- SMF_INTERFACE_NAME_FOR_N4=eth0
|
||||
- SMF_INTERFACE_NAME_FOR_SBI=eth0
|
||||
- SMF_INTERFACE_PORT_FOR_SBI=80
|
||||
- SMF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
|
||||
- SMF_API_VERSION=v1
|
||||
- DEFAULT_DNS_IPV4_ADDRESS=172.21.3.100
|
||||
- DEFAULT_DNS_SEC_IPV4_ADDRESS=4.4.4.4
|
||||
- AMF_IPV4_ADDRESS=0.0.0.0
|
||||
- AMF_PORT=80
|
||||
- AMF_API_VERSION=v1
|
||||
- AMF_FQDN=oai-amf
|
||||
- UDM_IPV4_ADDRESS=127.0.0.1
|
||||
- UDM_PORT=80
|
||||
- UDM_API_VERSION=v1
|
||||
- UDM_FQDN=localhost
|
||||
- UPF_IPV4_ADDRESS=192.168.71.134
|
||||
- UPF_FQDN_0=oai-spgwu
|
||||
- NRF_IPV4_ADDRESS=192.168.71.130
|
||||
- NRF_PORT=80
|
||||
- NRF_API_VERSION=v1
|
||||
- NRF_FQDN=oai-nrf
|
||||
- REGISTER_NRF=yes
|
||||
- DISCOVER_UPF=yes
|
||||
- USE_FQDN_DNS=yes
|
||||
- DNN_NI0=oai
|
||||
- TYPE0=IPv4
|
||||
- DNN_RANGE0=12.1.1.2 - 12.1.1.127
|
||||
- NSSAI_SST0=1
|
||||
- NSSAI_SD0=0xFFFFFF
|
||||
- SESSION_AMBR_UL0=200Mbps
|
||||
- SESSION_AMBR_DL0=400Mbps
|
||||
- DNN_NI2=oai.ipv4
|
||||
depends_on:
|
||||
- oai-nrf
|
||||
- oai-amf
|
||||
volumes:
|
||||
- ../5g_rfsimulator/smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.133
|
||||
|
||||
oai-spgwu:
|
||||
container_name: "rfsim5g-oai-spgwu"
|
||||
image: oai-spgwu-tiny:august-dev
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- PID_DIRECTORY=/var/run
|
||||
- SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP=eth0
|
||||
- SGW_INTERFACE_NAME_FOR_SX=eth0
|
||||
- PGW_INTERFACE_NAME_FOR_SGI=eth0
|
||||
- NETWORK_UE_NAT_OPTION=yes
|
||||
- NETWORK_UE_IP=12.1.1.0/24
|
||||
- SPGWC0_IP_ADDRESS=192.168.71.133
|
||||
- BYPASS_UL_PFCP_RULES=no
|
||||
- MCC=208
|
||||
- MNC=99
|
||||
- MNC03=099
|
||||
- TAC=1
|
||||
- GTP_EXTENSION_HEADER_PRESENT=yes
|
||||
- GW_ID=1
|
||||
- REALM=openairinterface.org
|
||||
- ENABLE_5G_FEATURES=yes
|
||||
- REGISTER_NRF=yes
|
||||
- USE_FQDN_NRF=yes
|
||||
- UPF_FQDN_5G=oai-spgwu
|
||||
- NRF_IPV4_ADDRESS=192.168.71.130
|
||||
- NRF_PORT=80
|
||||
- NRF_API_VERSION=v1
|
||||
- NRF_FQDN=oai-nrf
|
||||
- NSSAI_SST_0=1
|
||||
- NSSAI_SD_0=0xffffff
|
||||
- DNN_0=oai
|
||||
depends_on:
|
||||
- oai-nrf
|
||||
- oai-smf
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_ADMIN
|
||||
cap_drop:
|
||||
- ALL
|
||||
privileged: true
|
||||
volumes:
|
||||
- ../5g_rfsimulator/spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/openair-spgwu-tiny/bin/spgwu-healthcheck.sh"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.134
|
||||
traffic_net:
|
||||
ipv4_address: 192.168.72.134
|
||||
|
||||
oai-ext-dn:
|
||||
image: ubuntu:bionic
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-ext-dn
|
||||
entrypoint: /bin/bash -c \
|
||||
"apt update; apt install -y procps iptables iproute2 iperf iputils-ping;"\
|
||||
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
|
||||
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
|
||||
depends_on:
|
||||
- oai-spgwu
|
||||
networks:
|
||||
traffic_net:
|
||||
ipv4_address: 192.168.72.135
|
||||
healthcheck:
|
||||
test: /bin/bash -c "ping -c 2 192.168.72.134"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
oai-gnb:
|
||||
image: oai-gnb:develop
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-gnb
|
||||
environment:
|
||||
RFSIMULATOR: server
|
||||
USE_VOLUMED_CONF: 'yes'
|
||||
USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time
|
||||
depends_on:
|
||||
- oai-ext-dn
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.140
|
||||
volumes:
|
||||
- ../../conf_files/gnb.sa.band66.u0.25prb.rfsim.conf:/opt/oai-gnb/etc/mounted.conf
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-softmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
oai-nr-ue:
|
||||
image: oai-nr-ue:develop
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-nr-ue
|
||||
environment:
|
||||
RFSIMULATOR: 192.168.71.140
|
||||
FULL_IMSI: '208990100001100'
|
||||
FULL_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
|
||||
OPC: 'C42449363BBAD02B66D16BC975D77CC1'
|
||||
DNN: oai
|
||||
NSSAI_SST: 1
|
||||
USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 25 --numerology 0 --band 66 -C 2152250000 --CO -400000000 --ssb 48 --nokrnmod --nokrnmod --log_config.global_log_options level,nocolor,time
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.150
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-uesoftmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
networks:
|
||||
public_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-public-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.71.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-public"
|
||||
traffic_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-traffic-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.72.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-traffic"
|
||||
@@ -461,7 +461,7 @@ install_soapy_from_source(){
|
||||
(
|
||||
cd /tmp
|
||||
echo "Downloading SoapySDR"
|
||||
rm -rf /tmp/soapysdr
|
||||
rm -rf /tmp/SoapySDR
|
||||
git clone -b soapy-sdr-0.7.0 --single-branch https://github.com/pothosware/SoapySDR.git
|
||||
cd SoapySDR
|
||||
#git checkout tags/release_003_010_001_001
|
||||
@@ -474,7 +474,7 @@ install_soapy_from_source(){
|
||||
$SUDO ldconfig
|
||||
cd /tmp
|
||||
echo "Downloading SoapyRemote"
|
||||
rm -rf /tmp/soapyremote
|
||||
rm -rf /tmp/SoapyRemote
|
||||
git clone -b soapy-remote-0.5.0 --single-branch https://github.com/pothosware/SoapyRemote.git
|
||||
cd SoapyRemote
|
||||
#git checkout tags/release_003_010_001_001
|
||||
@@ -838,21 +838,6 @@ install_simde_from_source(){
|
||||
cd /tmp/simde
|
||||
# brute force copy into /usr/include
|
||||
$SUDO \cp -rv ../simde /usr/include
|
||||
$SUDO patch /usr/include/simde/x86/avx.h << FIN
|
||||
--- /usr/include/simde/x86/avx.h.old 2022-10-03 19:17:39.828223432 +0200
|
||||
+++ /usr/include/simde/x86/avx.h 2022-10-05 16:19:55.086019445 +0200
|
||||
@@ -3643,6 +3643,9 @@
|
||||
simde__m256i simde_mm256_insertf128_si256(simde__m256i a, simde__m128i b, int im
|
||||
|
||||
return simde__m256i_from_private(a_);
|
||||
}
|
||||
+#if defined(SIMDE_X86_AVX_NATIVE)
|
||||
+ #define simde_mm256_insertf128_si256(a, b, imm8) _mm256_insertf128_si256(a, b, imm8)
|
||||
+#endif
|
||||
#if defined(SIMDE_X86_AVX_ENABLE_NATIVE_ALIASES)
|
||||
#undef _mm256_insertf128_si256
|
||||
#define _mm256_insertf128_si256(a, b, imm8) simde_mm256_insertf128_si256(a, b, imm8)
|
||||
FIN
|
||||
}
|
||||
|
||||
#################################################
|
||||
|
||||
155
common/platform_constants.h
Normal file
155
common/platform_constants.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
platform_constants.h
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER and Navid Nikaein
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __PLATFORM_CONSTANTS_H__
|
||||
#define __PLATFORM_CONSTANTS_H__
|
||||
#include "LTE_asn_constant.h"
|
||||
#include "NR_asn_constant.h"
|
||||
#define NR_MAXDRB 14
|
||||
|
||||
#ifdef JUMBO_FRAME
|
||||
#define NL_MAX_PAYLOAD 18000 /* this should cover the max mtu size*/
|
||||
#else
|
||||
#define NL_MAX_PAYLOAD 9000 /* this should cover the max mtu size*/
|
||||
#endif
|
||||
|
||||
#ifdef LARGE_SCALE
|
||||
#define NB_MODULES_MAX 128
|
||||
#define NB_NODE_MAX 128
|
||||
#else
|
||||
#define NB_MODULES_MAX 32
|
||||
#define NB_NODE_MAX 32
|
||||
#endif
|
||||
|
||||
#ifdef JUMBO_FRAME
|
||||
#define MAX_IP_PACKET_SIZE 10000 // 9000
|
||||
#else
|
||||
#if defined(OAI_NW_DRIVER_TYPE_ETHERNET)
|
||||
/* SR: When using ethernet network driver the packet size is 1512 :
|
||||
* 1500 bytes IP packet + 14 bytes ethernet header
|
||||
*/
|
||||
#define MAX_IP_PACKET_SIZE 1514
|
||||
#else
|
||||
#define MAX_IP_PACKET_SIZE 1500 // 3000
|
||||
#endif
|
||||
#endif
|
||||
// overwrite the previous deinitions
|
||||
|
||||
#define MAX_MODULES NB_MODULES_MAX
|
||||
#define MAX_NR_RRC_UE_CONTEXTS 64
|
||||
|
||||
#ifndef UE_EXPANSION
|
||||
#ifdef LARGE_SCALE
|
||||
#define MAX_MOBILES_PER_ENB 128
|
||||
#define MAX_MOBILES_PER_ENB_NB_IoT 128
|
||||
#define MAX_MOBILES_PER_GNB 128
|
||||
#define MAX_eNB 2
|
||||
#define MAX_gNB 2
|
||||
#else
|
||||
#define MAX_MOBILES_PER_ENB 40
|
||||
#define MAX_MOBILES_PER_ENB_NB_IoT 40
|
||||
#define MAX_MOBILES_PER_GNB 16
|
||||
#define MAX_eNB 2
|
||||
#define MAX_gNB 2
|
||||
#endif
|
||||
#else
|
||||
#define MAX_MOBILES_PER_ENB 256
|
||||
#define MAX_MOBILES_PER_ENB_NB_IoT 256
|
||||
#define MAX_MOBILES_PER_GNB 256
|
||||
#define MAX_eNB 2
|
||||
#define MAX_gNB 2
|
||||
#endif
|
||||
|
||||
#define NUMBER_OF_NR_UCI_STATS_MAX 16
|
||||
#define MAX_MANAGED_ENB_PER_MOBILE 2
|
||||
#define MAX_MANAGED_GNB_PER_MOBILE 2
|
||||
|
||||
/// NB-IOT
|
||||
#define NB_RB_MAX_NB_IOT (LTE_maxDRB_NB_r13 + 3) // MP: NB_IoT --> 2(DRB)+3(SRBs - 2 is not used) = 5
|
||||
|
||||
#define DEFAULT_RAB_ID 1
|
||||
|
||||
#define NB_RB_MAX (LTE_maxDRB + 3) /* was 11, now 14, maxDRB comes from asn1_constants.h, + 3 because of 3 SRB, one invisible id 0, then id 1 and 2 */
|
||||
#define NR_NB_RB_MAX (NR_maxDRB + 3)
|
||||
|
||||
#define NGAP_MAX_PDU_SESSION (256) /* As defined in TS 38.413 9.2.1.1 Range Bound for PDU Sessions. */
|
||||
#define NGAP_MAX_DRBS_PER_UE (32) /* As defined in TS 38.413 9.2.1.1 - maxnoofDRBs */
|
||||
|
||||
#define NB_RB_MBMS_MAX (LTE_maxSessionPerPMCH * LTE_maxServiceCount)
|
||||
|
||||
#define NB_RAB_MAX LTE_maxDRB /* was 8, now 11 */
|
||||
#define RAB_SHIFT1 9
|
||||
#define RAB_SHIFT2 3
|
||||
//#define RAB_OFFSET 0x0007
|
||||
#define RAB_OFFSET 0x000F
|
||||
#define RAB_OFFSET1 0x7E00
|
||||
#define RAB_OFFSET2 0x01F8
|
||||
#define DIR_OFFSET 0x8000
|
||||
#define DIR_SHIFT 15
|
||||
#define CH_OFFSET 0x0004
|
||||
#define CH_SHIFT 2
|
||||
|
||||
// RLC Entity
|
||||
#define RLC_TX_MAXSIZE 10000000
|
||||
#define RLC_RX_MAXSIZE 10000000
|
||||
|
||||
// RLC_AM_SEND_MRW
|
||||
#define SEND_MRW_OFF 15
|
||||
#define SEND_MRW_ON 240
|
||||
|
||||
// RLC_SEGMENTATION_INDICATION
|
||||
#define SEGMENTATION_NOT_ALLOWED 0
|
||||
#define SEGMENTATION_ALLOWED 1
|
||||
|
||||
// RLC_DELIVERY_OF_ERRONEOUS_SDU
|
||||
#define DELIVERY_OF_ERRONEOUS_SDU_NO 0
|
||||
#define DELIVERY_OF_ERRONEOUS_SDU_YES 1
|
||||
#define DELIVERY_OF_ERRONEOUS_SDU_NO_DETECT 2
|
||||
|
||||
// CBA constant
|
||||
#define NUM_MAX_CBA_GROUP 4
|
||||
|
||||
#ifndef __cplusplus
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
#ifndef null
|
||||
#define null 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define UNUSED_PARAM_MBMS_SESSION_ID 0
|
||||
#define UNUSED_PARAM_MBMS_SERVICE_ID 0
|
||||
|
||||
#define printk printf
|
||||
|
||||
#define UNUSED_VARIABLE(vARIABLE) (void)(vARIABLE)
|
||||
|
||||
#endif /* __PLATFORM_CONSTANTS_H__ */
|
||||
@@ -34,7 +34,7 @@
|
||||
#define __RAN_CONTEXT_H__
|
||||
|
||||
#include <pthread.h>
|
||||
#include "COMMON/platform_constants.h"
|
||||
#include "common/platform_constants.h"
|
||||
#include "PHY/defs_eNB.h"
|
||||
#include "PHY/types.h"
|
||||
#include "PHY/impl_defs_top.h"
|
||||
@@ -110,4 +110,6 @@ typedef struct {
|
||||
} RAN_CONTEXT_t;
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
#define NB_eNB_INST RC.nb_inst
|
||||
#endif
|
||||
|
||||
139
common/utils/netconf/DOC/netconf.md
Normal file
139
common/utils/netconf/DOC/netconf.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Netconf Server for O1 interface
|
||||
|
||||
## Specification
|
||||
|
||||
For this part please look into the [specification](../../../../specification/README.md) folder.
|
||||
|
||||
## Configuration
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
o1Config :
|
||||
{
|
||||
nfNodeId = "gnb-test01";
|
||||
netconfUsername = "netconf";
|
||||
netconfPassword = "netconf!";
|
||||
netconfPort = 58300;
|
||||
netconfHost = "192.168.5.207";
|
||||
vesUrl = "https://dcae-ves-collector:8443/eventListener/v7";
|
||||
vesBasicAuthUsername = "sample1";
|
||||
vesBasicAuthPassword = "sample1";
|
||||
vesNfVendorName = "OpenAirInterface";
|
||||
vesNfNamingCode = "OGNB";
|
||||
vesOamIpv6 = "";
|
||||
vesFtpServerPort = 21;
|
||||
vesFtpServerListenAddress = "0.0.0.0";
|
||||
vesFtpServerUrl = "ftp://netconfr:netconf@gnodeb01-test:21";
|
||||
demoAlarmingInterval = 30;
|
||||
};
|
||||
```
|
||||
|
||||
Properties:
|
||||
|
||||
| property | type | mandatory | description |
|
||||
| -------- | ---- | --------- | ----------- |
|
||||
| nfNodeId | string |true | network function node-id to get mounted via netconf |
|
||||
| netconfUsername | string | true | username to access netconf server(at the moment hardcoded)|
|
||||
| netconfPassword | string | true | password to access netconf server(at the moment hardcoded)|
|
||||
| netconfPort | uint_16 | true | port to listen on for netconf server(at the moment hardcoded to 830).|
|
||||
| netconfHost | string | true | |
|
||||
| vesUrl| string | false | url to send VES messages to. If not set, complete VES functionality is disabled |
|
||||
| vesBasicAuthUsername| string | if vesUrl | basic auth username for the VES collector |
|
||||
| vesBasicAuthPassword | string | if vesUrl | basic auth password for the VES collector |
|
||||
| vesNfVendorName | string | if vesUrl | vendor name to be sent in the VES messages |
|
||||
| vesNfNamingCode | string | if vesUrl | nfNamingCode to be sent in the VES messages |
|
||||
| vesOamIpv6 | string | false | |
|
||||
| vesFtpServerPort | uint_16 | false ||
|
||||
| vesFtpServerListenAddress| string | false | |
|
||||
| vesFtpServerUrl | string | false | |
|
||||
| demoAlarmingInterval | unit_16| false | interval in seconds to send and clear a demo alarm sent via VES |
|
||||
|
||||
|
||||
|
||||
The VES functionality can be disabled by just not setting the ```vesUrl```. With this all of the ```vesXXX``` properties are obsolete.
|
||||
|
||||
|
||||
## Software Architecture
|
||||
|
||||
```
|
||||
|----------------------------------------------------------------------------------------------|
|
||||
| OAI container | Netopeer2 server | | FTPes-server | |
|
||||
| |--------------------| |------------------| |
|
||||
| | | |
|
||||
| | | |
|
||||
| |--------------------| | |
|
||||
| | sysrepo | | |
|
||||
| | (datastore) | | |
|
||||
| |--------------------| | |
|
||||
| gnb.conf | | |
|
||||
| | | | |
|
||||
| ------------------------------------------------------------------------------------------ |
|
||||
| | nr-softmodem | | | |
|
||||
| | | | | |
|
||||
| | read-oper- edit-config- | |
|
||||
| | callbacks callbacks | |
|
||||
| | ves-client | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
|----------------------------------------------------------------------------------------------|
|
||||
```
|
||||
|
||||
|
||||
## Minimal Deployment Architecture
|
||||
|
||||
This picture is only showing the directly connected components to the OAI gNodeB. This is NOT a complete deployment since there a some more components needed to make everything work together.
|
||||
|
||||
```
|
||||
smo-network-----|------------------------------------------------------------------------
|
||||
| | |
|
||||
|-------------------| |--------------------| |-----------------|
|
||||
| SDNC | | VES-Collector | | FileCollector |
|
||||
| | | | | |
|
||||
|-------------------| |--------------------| |-----------------|
|
||||
| | |
|
||||
oam-network-----|-------------------------|----------------------|-------------------
|
||||
| | |
|
||||
|--------------------------------------------------------------------|
|
||||
| | NETCONF-Server | | VES-Client | | FTPes-Server | |
|
||||
| |----------------| |------------| |--------------| |
|
||||
| |
|
||||
| OAI gNodeB |
|
||||
| |
|
||||
|--------------------------------------------------------------------|
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Integration Deployment And Usage
|
||||
|
||||
for this documentation please check the [integration](../../../../integration/README.md) folder.
|
||||
|
||||
### PNF Registration
|
||||
|
||||
By starting up the gNodeB should automatically sends a pnfRegistration message to the VES-Collector. This message will be received by the SDNC and creates then a NETCONF connection between the itself and the device.
|
||||
|
||||
### PNF Alarming
|
||||
|
||||
If the ```demoAlarmingInterval``` is set, every n seconds there will be a alarm notification sent via VES to raise and clear the demoAlarm.
|
||||
|
||||
|
||||
### PNF Performance Data
|
||||
|
||||
To transmit performance data to the ONAP system there is a ```file-ready``` event sent to the VES-Collector which contains the information of the file to transmit. The will be collected by the File-Collector via FTPes or SFTP.
|
||||
|
||||
For demo purpose we have now created a trigger inside which is sending such a file ready event. To do this you have to do the following steps.
|
||||
|
||||
* Open the ConfigApp with the gNodeB
|
||||
```
|
||||
http://localhost:8080/odlux/index.html#/configuration/{node-id}/_3gpp-common-managed-element:ManagedElement[OAI%20gNodeB]
|
||||
```
|
||||
* _3gpp-common-managed-element > Attributes
|
||||
* click edit on the top right corner
|
||||
* set the userLabel property to ```pmData``` and click save to trigger the ```file-ready``` event once.
|
||||
* afterwards you have to reset it to ```disabled``` and back if you want to trigger it again
|
||||
* up to now the file and its data is hardcoded. But it shows that the workflow is working
|
||||
|
||||
41
common/utils/netconf/constants.h
Normal file
41
common/utils/netconf/constants.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
// constants to set
|
||||
#define MANAGED_ELEMENT_ID "OAI gNodeB"
|
||||
#define MANAGED_ELEMENT_GNBDUFUNCTION_ID "OAI-DU"
|
||||
#define MANAGED_ELEMENT_GNBCUCPFUNCTION_ID "OAI-CUCP"
|
||||
#define MANAGED_ELEMENT_GNBCUUPFUNCTION_ID "OAI-CUUP"
|
||||
#define MANAGED_ELEMENT_GNBDUFUNCTION_BWDUPLINK_NAME "Uplink"
|
||||
#define MANAGED_ELEMENT_GNBDUFUNCTION_BWDDOWNLINK_NAME "Downlink"
|
||||
|
||||
|
||||
// generated xpaths out of the constants
|
||||
#define XPATH_MANAGED_ELEMENT_BASE1 "/_3gpp-common-managed-element:ManagedElement[id='" MANAGED_ELEMENT_ID
|
||||
#define XPATH_MANAGED_ELEMENT_BASE XPATH_MANAGED_ELEMENT_BASE1 "']"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BASE1 XPATH_MANAGED_ELEMENT_BASE "/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BASE2 XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BASE1 MANAGED_ELEMENT_GNBDUFUNCTION_ID
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BASE XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BASE2 "']"
|
||||
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_BASE1 XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BASE "/_3gpp-nr-nrm-bwp:BWP[id='"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_BASE2 XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_BASE1 MANAGED_ELEMENT_GNBDUFUNCTION_BWDDOWNLINK_NAME
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_BASE XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_BASE2 "']"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_BASE XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_BASE "/attributes"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_BWPCONTEXT XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_BASE "/bwpContext"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_ISINITIALBWP XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_BASE "/isInitialBwp"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_SUBCARRIERSPACING XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_BASE "/subCarrierSpacing"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_CYCLICPREFIX XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_BASE "/cyclicPrefix"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_STARTRB XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_BASE "/startRB"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_NUMBEROFRBS XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPDOWNLINK_ATTRIBUTES_BASE "/numberOfRBs"
|
||||
|
||||
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_BASE1 XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BASE "/_3gpp-nr-nrm-bwp:BWP[id='"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_BASE2 XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_BASE1 MANAGED_ELEMENT_GNBDUFUNCTION_BWDUPLINK_NAME
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_BASE XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_BASE2 "']"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_BASE XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_BASE "/attributes"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_BWPCONTEXT XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_BASE "/bwpContext"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_ISINITIALBWP XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_BASE "/isInitialBwp"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_SUBCARRIERSPACING XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_BASE "/subCarrierSpacing"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_CYCLICPREFIX XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_BASE "/cyclicPrefix"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_STARTRB XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_BASE "/startRB"
|
||||
#define XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_NUMBEROFRBS XPATH_MANAGED_ELEMENT_GNBDUFUNCTION_BWPUPLINK_ATTRIBUTES_BASE "/numberOfRBs"
|
||||
|
||||
114
common/utils/netconf/netconf.c
Normal file
114
common/utils/netconf/netconf.c
Normal file
@@ -0,0 +1,114 @@
|
||||
#include "netconf.h"
|
||||
#include "o1config.h"
|
||||
#include "netconf_session.h"
|
||||
#include "netconf_log.h"
|
||||
#include "utils.h"
|
||||
#include "ves.h"
|
||||
#include "ves_demo_alarm.h"
|
||||
|
||||
int netconf_init(void) {
|
||||
int rc = 0;
|
||||
|
||||
//get configuration
|
||||
o1_config_t config = {0};
|
||||
rc = o1_config_read(&config);
|
||||
if(rc != 0) {
|
||||
netconf_log_error("o1_config_read() failed");
|
||||
goto failed;
|
||||
}
|
||||
o1_config_print(&config);
|
||||
|
||||
//init netconf
|
||||
sr_log_stderr(SR_LL_WRN);
|
||||
rc = netconf_session_init();
|
||||
if(rc != 0) {
|
||||
netconf_log_error("netconf_session_init() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
//init ves
|
||||
if (o1_config_is_ves_enabled(&config)) {
|
||||
ves_header_t data = {
|
||||
hostname: get_hostname(),
|
||||
nf_naming_code: config.ves_nf_naming_code,
|
||||
nf_vendor_name: config.ves_nf_vendor_name,
|
||||
pnf_id: config.netconf_node_id
|
||||
};
|
||||
|
||||
ves_config_t ves_config = {
|
||||
url: config.ves_url,
|
||||
username: config.ves_basicauth_username,
|
||||
password: config.ves_basicauth_password
|
||||
};
|
||||
|
||||
rc = ves_init(&ves_config, &data);
|
||||
free(data.hostname);
|
||||
|
||||
if(rc != 0) {
|
||||
netconf_log_error("ves_init() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ves_registration_data_t pnf_reg_data= {
|
||||
pnf_username: config.netconf_username,
|
||||
pnf_password: config.netconf_password,
|
||||
pnf_ip_v4_address: config.netconf_host,
|
||||
pnf_ip_v6_address: config.ves_oam_ipv6,
|
||||
pnf_port: config.netconf_port,
|
||||
mac_address: "12:34:56:78:90:AB", //TODO get it programatically
|
||||
vendor: config.ves_nf_vendor_name,
|
||||
model: "testModel",
|
||||
type: "gNB",
|
||||
is_tls: false
|
||||
};
|
||||
|
||||
rc = ves_pnf_registration_execute(&pnf_reg_data);
|
||||
if(rc != 0) {
|
||||
netconf_log_error("ves_pnf_registration_execute() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if(o1_config_is_demoalarming_enabled(&config)){
|
||||
ves_demo_alarm_start(&config);
|
||||
}
|
||||
}
|
||||
|
||||
rc = netconf_disable_nacm(netconf_session_running);
|
||||
if(rc != 0) {
|
||||
netconf_log("netconf_disable_nacm() failed\n");
|
||||
}
|
||||
|
||||
printf("netconf_demo_populate()...\n");
|
||||
rc = netconf_demo_populate();
|
||||
if(rc != 0) {
|
||||
netconf_log_error("netconf_demo_subscribe_edit_change() failed");
|
||||
}
|
||||
|
||||
printf("netconf_demo_subscribe_edit_change()...\n");
|
||||
rc = netconf_demo_subscribe_edit_change();
|
||||
if(rc != 0) {
|
||||
netconf_log_error("netconf_demo_subscribe_edit_change() failed");
|
||||
}
|
||||
|
||||
printf("netconf_demo_subscribe_operational()...\n");
|
||||
rc = netconf_demo_subscribe_operational();
|
||||
if(rc != 0) {
|
||||
netconf_log_error("netconf_demo_subscribe_operational() failed");
|
||||
}
|
||||
|
||||
o1_config_free(&config);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
ves_free();
|
||||
o1_config_free(&config);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int netconf_free(void) {
|
||||
ves_free();
|
||||
netconf_session_free();
|
||||
|
||||
return 0;
|
||||
}
|
||||
11
common/utils/netconf/netconf.h
Normal file
11
common/utils/netconf/netconf.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <sysrepo.h>
|
||||
|
||||
int netconf_init(void);
|
||||
int netconf_free(void);
|
||||
|
||||
int netconf_disable_nacm(sr_session_ctx_t *session);
|
||||
int netconf_demo_populate(void);
|
||||
int netconf_demo_subscribe_edit_change();
|
||||
int netconf_demo_subscribe_operational();
|
||||
38
common/utils/netconf/netconf_CMakeLists.wip.txt
Normal file
38
common/utils/netconf/netconf_CMakeLists.wip.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
set(NETCONFROOT ${OPENAIR_DIR}/common/utils/netconf )
|
||||
|
||||
set(NETCONFROOTSRV_SOURCE
|
||||
${NETCONFROOT}/netconf.c
|
||||
${NETCONFROOT}/netconf_demos.c
|
||||
${NETCONFROOT}/netconf_session.c
|
||||
${NETCONFROOT}/o1config.c
|
||||
${NETCONFROOT}/utils.c
|
||||
${NETCONFROOT}/ves.c
|
||||
)
|
||||
|
||||
add_library(netconfsrv MODULE ${NETCONFSRV_SOURCE} )
|
||||
target_link_libraries(netconfsrv PRIVATE yang sysrepo )
|
||||
|
||||
foreach(NETCONFLIB enb gnb 4Gue 5Gue)
|
||||
set(NETCONFLIB_SRCS "")
|
||||
foreach(NETCONFLIB_ASRC measurements phycmd)
|
||||
set(NETCONFLIB_SRC ${OPENAIR_DIR}/common/utils/netconfsrv/netconfsrv_${NETCONFLIB}_${NETCONFLIB_ASRC}.c)
|
||||
if (EXISTS ${NETCONFLIB_SRC})
|
||||
set( NETCONFLIB_SRCS "${NETCONFLIB_SRC};${NETCONFLIB_SRCS}")
|
||||
endif()
|
||||
endforeach()
|
||||
if(NOT "${NETCONFLIB_SRCS}" STREQUAL "")
|
||||
message("Add ${NETCONFLIB} specific telnet functions in libnetconfsrv_${NETCONFLIB}.so")
|
||||
add_library(netconfsrv_${NETCONFLIB} MODULE ${NETCONFLIB_SRCS} )
|
||||
add_dependencies(netconfsrv netconfsrv_${NETCONFLIB})
|
||||
target_link_libraries(netconfsrv_${NETCONFLIB} PRIVATE asn1_nr_rrc asn1_lte_rrc)
|
||||
install(TARGETS netconfsrv_${NETCONFLIB} DESTINATION bin)
|
||||
else()
|
||||
message("No specific netconf functions for ${NETCONFLIB}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
install(TARGETS netconfsrv DESTINATION bin)
|
||||
|
||||
if (EXISTS "${OPENAIR_CMAKE}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_CMAKE}/ran_build/build")
|
||||
install(TARGETS netconfsrv DESTINATION ${OPENAIR_CMAKE}/ran_build/build)
|
||||
endif (EXISTS "${OPENAIR_CMAKE}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_CMAKE}/ran_build/build")
|
||||
353
common/utils/netconf/netconf_demos.c
Normal file
353
common/utils/netconf/netconf_demos.c
Normal file
@@ -0,0 +1,353 @@
|
||||
#include "netconf.h"
|
||||
#include "netconf_log.h"
|
||||
#include "netconf_session.h"
|
||||
#include "ves.h"
|
||||
|
||||
#include <sysrepo.h>
|
||||
#include <libyang/libyang.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static int test_edit_callback(sr_session_ctx_t *session, uint32_t sub_id, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data);
|
||||
static int test_oper_callback(sr_session_ctx_t *session, uint32_t sub_id, const char *module_name, const char *path, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data);
|
||||
|
||||
int netconf_disable_nacm(sr_session_ctx_t *session) {
|
||||
#define IETF_NETCONF_ACM_ENABLE_NACM_SCHEMA_XPATH "/ietf-netconf-acm:nacm/enable-nacm"
|
||||
#define IETF_NETCONF_ACM_GROUPS_SCHEMA_XPATH "/ietf-netconf-acm:nacm/groups"
|
||||
#define IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH "/ietf-netconf-acm:nacm/rule-list"
|
||||
|
||||
int rc = 0;
|
||||
rc = sr_set_item_str(session, IETF_NETCONF_ACM_ENABLE_NACM_SCHEMA_XPATH, "true", 0, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_set_item_str() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rc = sr_set_item_str(session, IETF_NETCONF_ACM_GROUPS_SCHEMA_XPATH"/group[name='sudo']/user-name", "netconf", 0, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_set_item_str() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rc = sr_set_item_str(session, IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH"[name='sudo-rules']/group", "sudo", 0, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_set_item_str() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rc = sr_set_item_str(session, IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH"[name='sudo-rules']/rule[name='allow-all-sudo']/module-name", "*", 0, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_set_item_str() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rc = sr_set_item_str(session, IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH"[name='sudo-rules']/rule[name='allow-all-sudo']/path", "/", 0, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_set_item_str() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rc = sr_set_item_str(session, IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH"[name='sudo-rules']/rule[name='allow-all-sudo']/access-operations", "*", 0, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_set_item_str() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rc = sr_set_item_str(session, IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH"[name='sudo-rules']/rule[name='allow-all-sudo']/action", "permit", 0, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_set_item_str() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rc = sr_set_item_str(session, IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH"[name='sudo-rules']/rule[name='allow-all-sudo']/comment", "Corresponds all the rules under the sudo group as defined in O-RAN.WG4.MP.0-v05.00", 0, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_set_item_str() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rc = sr_apply_changes(session, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_apply_changes() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
sr_discard_changes(session);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int netconf_demo_populate(void) {
|
||||
int rc = 0;
|
||||
|
||||
const char *list_running[] = {
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']",
|
||||
0,
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']",
|
||||
0,
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/attributes/vnfParametersList[vnfInstanceId='SDNR_NODE_ID']",
|
||||
0,
|
||||
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']",
|
||||
0,
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/attributes/bwpContext",
|
||||
"DL",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/attributes/isInitialBwp",
|
||||
"INITIAL",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/attributes/subCarrierSpacing",
|
||||
"60",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/attributes/cyclicPrefix",
|
||||
"NORMAL",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/attributes/startRB",
|
||||
"0",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/attributes/numberOfRBs",
|
||||
"2",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/ThresholdMonitor[id='Threshold']",
|
||||
0,
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/ThresholdMonitor[id='Threshold']/attributes/administrativeState",
|
||||
"UNLOCKED",
|
||||
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']",
|
||||
0,
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/attributes/bwpContext",
|
||||
"UL",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/attributes/isInitialBwp",
|
||||
"INITIAL",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/attributes/subCarrierSpacing",
|
||||
"15",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/attributes/cyclicPrefix",
|
||||
"EXTENDED",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/attributes/startRB",
|
||||
"0",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/attributes/numberOfRBs",
|
||||
"2",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/ThresholdMonitor[id='Threshold']",
|
||||
0,
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/ThresholdMonitor[id='Threshold']/attributes/administrativeState",
|
||||
"UNLOCKED",
|
||||
|
||||
//alarms
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/AlarmList[id='CUUP-alarms']",
|
||||
0,
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/AlarmList[id='CUUP-alarms']/attributes/administrativeState",
|
||||
"UNLOCKED",
|
||||
|
||||
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/AlarmList[id='CUUP-alarms']/attributes/alarmRecords[alarmId='alarm-id-01']",
|
||||
0,
|
||||
|
||||
//mandatory nodes
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/attributes/priorityLabel",
|
||||
"5",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/attributes/priorityLabel",
|
||||
"6",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/attributes/gNBId",
|
||||
"7",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/attributes/gNBIdLength",
|
||||
"23",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/attributes/gNBDUId",
|
||||
"8",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/attributes/vnfParametersList[vnfInstanceId='SDNR_NODE_ID']/autoScalable",
|
||||
"true",
|
||||
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/attributes/priorityLabel",
|
||||
"9",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/attributes/priorityLabel",
|
||||
"10",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/ThresholdMonitor[id='Threshold']/attributes/thresholdInfoList[idx='0']/thresholdLevel",
|
||||
"12",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/ThresholdMonitor[id='Threshold']/attributes/thresholdInfoList[idx='0']/thresholdLevel",
|
||||
"13",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/ThresholdMonitor[id='Threshold']/attributes/thresholdInfoList[idx='0']/thresholdDirection",
|
||||
"UP",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/ThresholdMonitor[id='Threshold']/attributes/thresholdInfoList[idx='0']/thresholdDirection",
|
||||
"UP",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/ThresholdMonitor[id='Threshold']/attributes/thresholdInfoList[idx='0']/thresholdValue",
|
||||
"14",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/ThresholdMonitor[id='Threshold']/attributes/thresholdInfoList[idx='0']/thresholdValue",
|
||||
"15",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Downlink']/ThresholdMonitor[id='Threshold']/attributes/monitorGranularityPeriod",
|
||||
"16",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/_3gpp-nr-nrm-bwp:BWP[id='Uplink']/ThresholdMonitor[id='Threshold']/attributes/monitorGranularityPeriod",
|
||||
"17",
|
||||
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
const char *list_operational[] = {
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/_3gpp-nr-nrm-gnbdufunction:GNBDUFunction[id='OAI-DU']/attributes/rimRSReportConf[reportInterval='1000']/reportIndicator",
|
||||
"DISABLED",
|
||||
|
||||
//alarms
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/AlarmList[id='CUUP-alarms']/attributes/operationalState",
|
||||
"ENABLED",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/AlarmList[id='CUUP-alarms']/attributes/numOfAlarmRecords",
|
||||
"1",
|
||||
"/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/AlarmList[id='CUUP-alarms']/attributes/lastModification",
|
||||
"2023-02-07T08:44:26.0Z",
|
||||
0
|
||||
};
|
||||
|
||||
const char **l = list_running;
|
||||
while(*l) {
|
||||
const char *xpath = *l;
|
||||
const char *value = *(l + 1);
|
||||
netconf_log("[config] populating %s with %s.. ", xpath, value);
|
||||
rc = sr_set_item_str(netconf_session_running, xpath, value, 0, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("error on line %d", __LINE__);
|
||||
}
|
||||
|
||||
l += 2;
|
||||
}
|
||||
|
||||
rc = sr_apply_changes(netconf_session_running, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("error on sr_apply_changes line %d", __LINE__);
|
||||
}
|
||||
|
||||
l = list_operational;
|
||||
while(*l) {
|
||||
const char *xpath = *l;
|
||||
const char *value = *(l + 1);
|
||||
netconf_log("[oper] populating %s with %s.. ", xpath, value);
|
||||
rc = sr_set_item_str(netconf_session_operational, xpath, value, 0, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("error on line %d", __LINE__);
|
||||
}
|
||||
|
||||
l += 2;
|
||||
}
|
||||
|
||||
rc = sr_apply_changes(netconf_session_operational, 0);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("error on sr_apply_changes line %d", __LINE__);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int netconf_demo_subscribe_edit_change() {
|
||||
const char *xpath = "/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/attributes/userLabel";
|
||||
int rc = sr_module_change_subscribe(netconf_session_running, "_3gpp-common-managed-element", xpath, test_edit_callback, NULL, 0, 0, &netconf_session_subscription);
|
||||
if (rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_module_change_subscribe() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
failed:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int netconf_demo_subscribe_operational() {
|
||||
static uint32_t counter = 1;
|
||||
|
||||
const char *xpath = "/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/attributes";
|
||||
int rc = sr_oper_get_subscribe(netconf_session_operational, "_3gpp-common-managed-element", xpath, test_oper_callback, &counter, SR_SUBSCR_DEFAULT, &netconf_session_subscription);
|
||||
if(rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_oper_get_subscribe() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int test_edit_callback(sr_session_ctx_t *session, uint32_t sub_id, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data) {
|
||||
sr_change_iter_t *it = NULL;
|
||||
int rc = SR_ERR_OK;
|
||||
char path[512];
|
||||
sr_change_oper_t oper;
|
||||
sr_val_t *old_value = NULL;
|
||||
sr_val_t *new_value = NULL;
|
||||
|
||||
(void)sub_id;
|
||||
(void)request_id;
|
||||
(void)private_data;
|
||||
|
||||
|
||||
if(event == SR_EV_CHANGE) {
|
||||
if (xpath) {
|
||||
sprintf(path, "%s//.", xpath);
|
||||
}
|
||||
else {
|
||||
sprintf(path, "/%s:*//.", module_name);
|
||||
}
|
||||
|
||||
rc = sr_get_changes_iter(session, path, &it);
|
||||
if (rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_get_changes_iter() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
while ((rc = sr_get_change_next(session, it, &oper, &old_value, &new_value)) == SR_ERR_OK) {
|
||||
if((oper == SR_OP_CREATED) || (oper == SR_OP_MODIFIED)) {
|
||||
if(strcmp("/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/attributes/userLabel", new_value->xpath) == 0) {
|
||||
if(strcmp(new_value->data.string_val, "enabled") == 0) {
|
||||
printf("enabled\n");
|
||||
}
|
||||
else if(strcmp(new_value->data.string_val, "disabled") == 0) {
|
||||
printf("disabled\n");
|
||||
}
|
||||
else if(strstr(new_value->data.string_val, "pmData") == new_value->data.string_val) {
|
||||
ves_file_ready_t pm_data = {
|
||||
.expires_on = "2099-12-31T235959.0Z",
|
||||
.filesize = 1234,
|
||||
.filelocation = "/ftp/test.gz"
|
||||
};
|
||||
|
||||
int rc = ves_pnf_pmdata_fileready_execute(&pm_data);
|
||||
if(rc != 0) {
|
||||
netconf_log_error("ves_pnf_pmdata_fileready_execute() failed");
|
||||
}
|
||||
}
|
||||
else {
|
||||
return SR_ERR_VALIDATION_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sr_free_val(old_value);
|
||||
sr_free_val(new_value);
|
||||
}
|
||||
|
||||
sr_free_change_iter(it);
|
||||
}
|
||||
return SR_ERR_OK;
|
||||
|
||||
failed:
|
||||
return SR_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
static int test_oper_callback(sr_session_ctx_t *session, uint32_t sub_id, const char *module_name, const char *path, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data) {
|
||||
uint32_t *counter = private_data;
|
||||
(void)session;
|
||||
(void)sub_id;
|
||||
(void)module_name;
|
||||
(void)path;
|
||||
(void)request_xpath;
|
||||
(void)request_id;
|
||||
|
||||
const char *xpath = "/_3gpp-common-managed-element:ManagedElement[id='OAI gNodeB']/attributes/SupportedPerfMetricGroup/granularityPeriods";
|
||||
|
||||
char value[10];
|
||||
sprintf(value, "%d", *counter);
|
||||
struct lyd_node *node;
|
||||
LY_ERR rc = lyd_new_path(*parent, 0, xpath, value, 0, &node);
|
||||
if(rc != LY_SUCCESS) {
|
||||
netconf_log_error("lyd_new_path() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
(*counter)++;
|
||||
return SR_ERR_OK;
|
||||
|
||||
failed:
|
||||
return SR_ERR_INTERNAL;
|
||||
}
|
||||
9
common/utils/netconf/netconf_log.h
Normal file
9
common/utils/netconf/netconf_log.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// #define netconf_log_error(format, args...) fprintf(stderr, format, ## args);
|
||||
#define netconf_log_error(format, ...) { fprintf(stderr, "\033[1;31m[err/:%5d]\033[0m ", __LINE__); fprintf(stderr, format, ##__VA_ARGS__); fprintf(stderr, "\n"); }
|
||||
|
||||
// #define netconf_log(format, args...) fprintf(stderr, format, ## args);
|
||||
#define netconf_log(format, ...) { fprintf(stdout, "\033[1m[log/:%5d]\033[0m ", __LINE__); fprintf(stdout, format, ##__VA_ARGS__); fprintf(stdout, "\n"); }
|
||||
62
common/utils/netconf/netconf_session.c
Normal file
62
common/utils/netconf/netconf_session.c
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "netconf_session.h"
|
||||
#include "netconf_log.h"
|
||||
|
||||
sr_conn_ctx_t *netconf_session_connection = 0;
|
||||
sr_session_ctx_t *netconf_session_running = 0;
|
||||
sr_session_ctx_t *netconf_session_operational = 0;
|
||||
const struct ly_ctx *netconf_session_context = 0;
|
||||
sr_subscription_ctx_t *netconf_session_subscription = 0;
|
||||
|
||||
int netconf_session_init(void) {
|
||||
int rc = SR_ERR_OK;
|
||||
|
||||
/* connect to sysrepo */
|
||||
rc = sr_connect(0, &netconf_session_connection);
|
||||
if(SR_ERR_OK != rc) {
|
||||
netconf_log_error("sr_connect failed");
|
||||
goto netconf_session_init_cleanup;
|
||||
}
|
||||
|
||||
/* start session */
|
||||
rc = sr_session_start(netconf_session_connection, SR_DS_OPERATIONAL, &netconf_session_operational);
|
||||
if (rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_session_start operational failed");
|
||||
goto netconf_session_init_cleanup;
|
||||
}
|
||||
|
||||
rc = sr_session_start(netconf_session_connection, SR_DS_RUNNING, &netconf_session_running);
|
||||
if (rc != SR_ERR_OK) {
|
||||
netconf_log_error("sr_session_start running failed");
|
||||
goto netconf_session_init_cleanup;
|
||||
}
|
||||
|
||||
/* get context */
|
||||
netconf_session_context = sr_acquire_context(netconf_session_connection);
|
||||
if(netconf_session_context == 0) {
|
||||
netconf_log_error("sr_acquire_context failed");
|
||||
goto netconf_session_init_cleanup;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
netconf_session_init_cleanup:
|
||||
return 1;
|
||||
}
|
||||
|
||||
void netconf_session_free(void) {
|
||||
if(netconf_session_subscription) {
|
||||
sr_unsubscribe(netconf_session_subscription);
|
||||
}
|
||||
|
||||
sr_release_context(netconf_session_connection);
|
||||
|
||||
sr_session_stop(netconf_session_operational);
|
||||
sr_session_stop(netconf_session_running);
|
||||
|
||||
sr_disconnect(netconf_session_connection);
|
||||
|
||||
netconf_session_connection = 0;
|
||||
netconf_session_running = 0;
|
||||
netconf_session_operational = 0;
|
||||
netconf_session_context = 0;
|
||||
}
|
||||
13
common/utils/netconf/netconf_session.h
Normal file
13
common/utils/netconf/netconf_session.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <libyang/libyang.h>
|
||||
#include <sysrepo.h>
|
||||
|
||||
extern sr_conn_ctx_t *netconf_session_connection;
|
||||
extern sr_session_ctx_t *netconf_session_running;
|
||||
extern sr_session_ctx_t *netconf_session_operational;
|
||||
extern const struct ly_ctx *netconf_session_context;
|
||||
extern sr_subscription_ctx_t *netconf_session_subscription;
|
||||
|
||||
int netconf_session_init(void);
|
||||
void netconf_session_free(void);
|
||||
111
common/utils/netconf/o1config.c
Normal file
111
common/utils/netconf/o1config.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#include "o1config.h"
|
||||
#include "netconf_log.h"
|
||||
#include <common/utils/assertions.h>
|
||||
#include <common/utils/LOG/log.h>
|
||||
|
||||
#define simOpt PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED
|
||||
#define simOptMandatory PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED|PARAMFLAG_MANDATORY
|
||||
|
||||
static int o1_validate_config(o1_config_t* config);
|
||||
|
||||
int o1_config_read(o1_config_t* config) {
|
||||
memset(config, 0, sizeof(o1_config_t));
|
||||
|
||||
paramdef_t o1config_params[] = {
|
||||
{"nfNodeId", "nodeId for oam for ves mount package\n", simOpt, strptr:&config->netconf_node_id, defstrval:"gnb-test01", TYPE_STRING, 0 },
|
||||
{"netconfUsername", "username for netconf interface\n", simOpt, strptr:&config->netconf_username, defstrval:"netconf", TYPE_STRING, 0 },
|
||||
{"netconfPassword", "password for netconf interface\n", simOpt, strptr:&config->netconf_password, defstrval:"netconf!", TYPE_STRING, 0 },
|
||||
{"netconfPort", "port on host device for netconf interface\n", simOpt, u16ptr:&(config->netconf_port), defuintval:830, TYPE_UINT16, 0 },
|
||||
{"netconfHost", "ip address on host device for netconf interface\n", simOpt, strptr:&config->netconf_host, defstrval:"0.0.0.0", TYPE_STRING, 0 },
|
||||
{"vesUrl", "ves endpoint url to send notifications to\n", simOpt, strptr:&config->ves_url, defstrval:"", TYPE_STRING, 0 },
|
||||
{"vesBasicAuthUsername", "ves endpoint username to authorize\n", simOpt, strptr:&config->ves_basicauth_username, defstrval:"", TYPE_STRING, 0 },
|
||||
{"vesBasicAuthPassword", "ves endpoint password to authorize\n", simOpt, strptr:&config->ves_basicauth_password, defstrval:"", TYPE_STRING, 0 },
|
||||
{"vesNfVendorName", "vendor name information for ves packages\n", simOpt, strptr:&config->ves_nf_vendor_name, defstrval:"OAI", TYPE_STRING, 0 },
|
||||
{"vesNfNamingCode", "naming code information for ves packages\n", simOpt, strptr:&config->ves_nf_naming_code, defstrval:"gNodeB", TYPE_STRING, 0 },
|
||||
{"vesOamIpv6", "oam ipv6 information for ves mount package\n", simOpt, strptr:&config->ves_oam_ipv6, defstrval:"", TYPE_STRING, 0 },
|
||||
{"vesFtpServerPort", "ftp server port to serve pm data\n", simOpt, u16ptr:&(config->ves_ftp_server_port), defuintval:21, TYPE_UINT16, 0 },
|
||||
{"vesFtpServerListenAddress", "ftp listen address to serve pm data\n", simOpt, strptr:&config->ves_ftp_listen_addr, defstrval:"0.0.0.0", TYPE_STRING, 0 },
|
||||
{"demoAlarmingInterval", "ves alarming interval in seconds for demoing alarms\n",simOpt, u16ptr:&(config->demo_alarming_interval), defuintval:0, TYPE_UINT16, 0 }
|
||||
};
|
||||
|
||||
#if defined(USE_TEST_CONFIG)
|
||||
(void)o1config_params; //unused
|
||||
config->netconf_node_id = strdup("gnb-test01");
|
||||
config->netconf_username = strdup("netconf");
|
||||
config->netconf_password = strdup("netconf!");
|
||||
config->netconf_port = 830;
|
||||
config->netconf_host = strdup("192.168.2.3");
|
||||
config->ves_url = strdup("https://192.168.5.207:8443/eventListener/v7");
|
||||
config->ves_basicauth_username = strdup("sample1");
|
||||
config->ves_basicauth_password = strdup("sample1");
|
||||
config->ves_nf_vendor_name = strdup("OpenAirInterface");
|
||||
config->ves_nf_naming_code = strdup("OGNB");
|
||||
config->ves_oam_ipv6 = strdup("");
|
||||
config->ves_ftp_server_port = 21;
|
||||
config->ves_ftp_listen_addr = strdup("0.0.0.0");
|
||||
config->demo_alarming_interval = 30;
|
||||
#else
|
||||
int ret = config_get(o1config_params, sizeof(o1config_params) / sizeof(paramdef_t), "o1Config");
|
||||
AssertFatal(ret >= 0, "configuration load couldn't be performed");
|
||||
#endif
|
||||
|
||||
return o1_validate_config(config);
|
||||
}
|
||||
|
||||
void o1_config_free(o1_config_t* config) {
|
||||
free(config->netconf_node_id);
|
||||
free(config->netconf_username);
|
||||
free(config->netconf_password);
|
||||
free(config->netconf_host);
|
||||
free(config->ves_url);
|
||||
free(config->ves_basicauth_username);
|
||||
free(config->ves_basicauth_password);
|
||||
free(config->ves_nf_vendor_name);
|
||||
free(config->ves_nf_naming_code);
|
||||
free(config->ves_oam_ipv6);
|
||||
free(config->ves_ftp_listen_addr);
|
||||
}
|
||||
|
||||
void o1_config_print(o1_config_t *config) {
|
||||
netconf_log("Printing config:");
|
||||
netconf_log("netconf_node_id: %s", config->netconf_node_id);
|
||||
netconf_log("netconf_username: %s", config->netconf_username);
|
||||
netconf_log("netconf_password: %s", config->netconf_password);
|
||||
netconf_log("netconf_port = %d", config->netconf_port);
|
||||
netconf_log("netconf_host: %s", config->netconf_host);
|
||||
netconf_log("ves_url: %s", config-> ves_url);
|
||||
netconf_log("ves_username: %s", config-> ves_basicauth_username);
|
||||
netconf_log("ves_password: %s", config-> ves_basicauth_password);
|
||||
netconf_log("ves_nf_vendor_name: %s", config->ves_nf_vendor_name);
|
||||
netconf_log("ves_nf_naming_code: %s", config->ves_nf_naming_code);
|
||||
netconf_log("ves_oam_ipv6: %s", config->ves_oam_ipv6);
|
||||
netconf_log("ves_ftp_server_port = %d", config->ves_ftp_server_port);
|
||||
netconf_log("ves_ftp_listen_addr: %s", config->ves_ftp_listen_addr);
|
||||
netconf_log("demo_alarming_interval: %d", config->demo_alarming_interval);
|
||||
netconf_log("=======");
|
||||
}
|
||||
|
||||
bool o1_config_is_ves_enabled(o1_config_t *config){
|
||||
return ((config->ves_url) && (strlen(config->ves_url) > 0));
|
||||
}
|
||||
|
||||
bool o1_config_is_demoalarming_enabled(o1_config_t *config) {
|
||||
return (config->demo_alarming_interval > 0);
|
||||
}
|
||||
|
||||
static int o1_validate_config(o1_config_t* config) {
|
||||
if (config == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
if (o1_config_is_ves_enabled(config)) {
|
||||
//verify vesNfNamingCode (has to be exactly 4 characters long)
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
29
common/utils/netconf/o1config.h
Normal file
29
common/utils/netconf/o1config.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/config/config_userapi.h>
|
||||
#include "common_lib.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *netconf_node_id;
|
||||
char *netconf_username;
|
||||
char *netconf_password;
|
||||
uint16_t netconf_port;
|
||||
char *netconf_host;
|
||||
char *ves_url;
|
||||
char *ves_basicauth_username;
|
||||
char *ves_basicauth_password;
|
||||
char *ves_nf_vendor_name;
|
||||
char *ves_nf_naming_code;
|
||||
char *ves_oam_ipv6;
|
||||
uint16_t ves_ftp_server_port;
|
||||
char *ves_ftp_listen_addr;
|
||||
uint16_t demo_alarming_interval; //send demo alarms every n seconds
|
||||
} o1_config_t;
|
||||
|
||||
|
||||
int o1_config_read(o1_config_t* config);
|
||||
void o1_config_free(o1_config_t* config);
|
||||
void o1_config_print(o1_config_t *config);
|
||||
bool o1_config_is_ves_enabled(o1_config_t *config);
|
||||
bool o1_config_is_demoalarming_enabled(o1_config_t *config);
|
||||
75
common/utils/netconf/oai_structs.h
Normal file
75
common/utils/netconf/oai_structs.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAND
|
||||
#define RO
|
||||
#define RW
|
||||
#define KEY
|
||||
|
||||
typedef struct oai_alarmRecords_thresholdInfo {
|
||||
RO MAND char *measurementType;
|
||||
RO MAND char *direction;
|
||||
RO char *thresholdLevel;
|
||||
RO char *thresholdValue;
|
||||
RO char *hysteresis;
|
||||
} oai_alarmRecords_thresholdInfo_t;
|
||||
|
||||
typedef struct oai_alarmRecords {
|
||||
RW KEY char *alarmId;
|
||||
RO MAND char *objectInstance;
|
||||
RO MAND char *notificationId; //int32_t
|
||||
RO char *alarmRaisedTime; //yang:date-and-time
|
||||
RO char *alarmChangedTime; //yang:date-and-time
|
||||
RO char *alarmClearedTime; //yang:date-and-time
|
||||
RO char *alarmType; //eventType
|
||||
RO char *probableCause;
|
||||
RO char *specificProblem;
|
||||
RW char *perceivedSeverity; //severity-level
|
||||
RO char *backedUpStatus;
|
||||
RO char *backUpObject;
|
||||
RO char *trendIndication;
|
||||
RO oai_alarmRecords_thresholdInfo_t *thresholdInfo;
|
||||
RO char *stateChangeDefinition;
|
||||
RO char *monitoredAttributes;
|
||||
RO char *proposedRepairActions;
|
||||
RO char *additionalText;
|
||||
// RO char *additionalInformation; <anydata>
|
||||
RO char *rootCauseIndicator;
|
||||
RO char *ackTime; //yang:date-and-time
|
||||
RW char *ackUserId;
|
||||
RW char *ackSystemId;
|
||||
RW char *ackState;
|
||||
RW char *clearUserId;
|
||||
RW char *clearSystemId;
|
||||
RO char *serviceUser;
|
||||
RO char *serviceProvider;
|
||||
RO char *securityAlarmDetector;
|
||||
} oai_alarmRecords_t;
|
||||
|
||||
typedef struct oai_BWP_ThresholdMonitor {
|
||||
RW KEY char *id;
|
||||
RW struct attributes {
|
||||
RW MAND char *bwpContext;
|
||||
RW MAND char *isInitialBwp;
|
||||
RW MAND char *subCarrierSpacing;
|
||||
RW MAND char *cyclicPrefix;
|
||||
RW MAND char *startRB;
|
||||
RW MAND char *numberOfRBs;
|
||||
};
|
||||
} oai_BWP_ThresholdMonitor_t;
|
||||
|
||||
typedef struct oai_BWP {
|
||||
RW KEY char *id;
|
||||
RW struct attributes {
|
||||
RW MAND char *bwpContext;
|
||||
RW MAND char *isInitialBwp;
|
||||
RW MAND char *subCarrierSpacing;
|
||||
RW MAND char *cyclicPrefix;
|
||||
RW MAND char *startRB;
|
||||
RW MAND char *numberOfRBs;
|
||||
};
|
||||
RW oai_BWP_ThresholdMonitor_t *ThresholdMonitor;
|
||||
|
||||
} oai_BWP_t;
|
||||
|
||||
118
common/utils/netconf/utils.c
Normal file
118
common/utils/netconf/utils.c
Normal file
@@ -0,0 +1,118 @@
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "utils.h"
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "netconf_log.h"
|
||||
|
||||
long int get_microseconds_since_epoch(void) {
|
||||
time_t t = time(0);
|
||||
struct timeval tv;
|
||||
long int useconds;
|
||||
|
||||
gettimeofday(&tv, 0);
|
||||
useconds = t*1000000 + tv.tv_usec; //add the microseconds to the seconds
|
||||
|
||||
return useconds;
|
||||
}
|
||||
|
||||
char *get_netconf_timestamp(void) {
|
||||
time_t rawtime = time(0);
|
||||
char *nctime = 0;
|
||||
|
||||
if (rawtime == -1) {
|
||||
netconf_log_error("time() failed");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
struct tm *ptm = gmtime(&rawtime);
|
||||
if (ptm == 0) {
|
||||
netconf_log_error("gmtime failed");
|
||||
}
|
||||
else {
|
||||
asprintf(&nctime, "%04d-%02d-%02dT%02d:%02d:%02d.0Z", ptm->tm_year + 1900, ptm->tm_mon + 1,
|
||||
ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
|
||||
}
|
||||
}
|
||||
|
||||
return nctime;
|
||||
}
|
||||
|
||||
char *str_replace(const char *orig, const char *rep, const char *with) {
|
||||
char *result; // the return string
|
||||
const char *ins; // the next insert point
|
||||
char *tmp; // varies
|
||||
int len_rep; // length of rep (the string to remove)
|
||||
int len_with; // length of with (the string to replace rep with)
|
||||
int len_front; // distance between rep and end of last rep
|
||||
int count; // number of replacements
|
||||
|
||||
// sanity checks and initialization
|
||||
if(!orig || !rep) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
len_rep = strlen(rep);
|
||||
if(len_rep == 0) {
|
||||
return 0; // empty rep causes infinite loop during count
|
||||
}
|
||||
|
||||
if (!with) {
|
||||
with = "";
|
||||
}
|
||||
len_with = strlen(with);
|
||||
|
||||
// count the number of replacements needed
|
||||
ins = orig;
|
||||
for(count = 0; (tmp = strstr(ins, rep)); ++count) {
|
||||
ins = tmp + len_rep;
|
||||
}
|
||||
|
||||
tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
|
||||
|
||||
if(!result) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// first time through the loop, all the variable are set correctly
|
||||
// from here on,
|
||||
// tmp points to the end of the result string
|
||||
// ins points to the next occurrence of rep in orig
|
||||
// orig points to the remainder of orig after "end of rep"
|
||||
while(count--) {
|
||||
ins = strstr(orig, rep);
|
||||
len_front = ins - orig;
|
||||
tmp = strncpy(tmp, orig, len_front) + len_front;
|
||||
tmp = strcpy(tmp, with) + len_with;
|
||||
orig += len_front + len_rep; // move to next "end of rep"
|
||||
}
|
||||
|
||||
strcpy(tmp, orig);
|
||||
return result;
|
||||
}
|
||||
|
||||
char *str_replace_inplace(char *s, const char *rep, const char *with) {
|
||||
char *ret = str_replace(s, rep, with);
|
||||
free(s);
|
||||
if(ret == 0) {
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *get_hostname(void) {
|
||||
char hostname[1024];
|
||||
hostname[1023] = '\0';
|
||||
gethostname(hostname, 1023);
|
||||
return strdup(hostname);
|
||||
}
|
||||
|
||||
unsigned long int get_file_size(const char *filename) {
|
||||
struct stat st;
|
||||
stat(filename, &st);
|
||||
return st.st_size;
|
||||
}
|
||||
8
common/utils/netconf/utils.h
Normal file
8
common/utils/netconf/utils.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
long int get_microseconds_since_epoch(void);
|
||||
char *get_netconf_timestamp(void);
|
||||
char *str_replace(const char *orig, const char *rep, const char *with);
|
||||
char *str_replace_inplace(char *s, const char *rep, const char *with);
|
||||
char *get_hostname(void);
|
||||
unsigned long int get_file_size(const char *filename);
|
||||
822
common/utils/netconf/ves.c
Normal file
822
common/utils/netconf/ves.c
Normal file
@@ -0,0 +1,822 @@
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "ves.h"
|
||||
#include "utils.h"
|
||||
#include "netconf_log.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define VES_COMMON_HEADER_TEMPLATE "\"commonEventHeader\": {\
|
||||
\"domain\": \"@domain@\",\
|
||||
\"eventId\": \"@domain@_@eventType@\",\
|
||||
\"eventName\": \"@domain@_@eventType@\",\
|
||||
\"eventType\": \"@eventType@\",\
|
||||
\"sequence\": @seqId@,\
|
||||
\"priority\": \"@priority@\",\
|
||||
\"reportingEntityId\": \"\",\
|
||||
\"reportingEntityName\": \"@controllerName@\",\
|
||||
\"sourceId\": \"\",\
|
||||
\"sourceName\": \"@pnfId@\",\
|
||||
\"startEpochMicrosec\": @timestamp@,\
|
||||
\"lastEpochMicrosec\": @timestamp@,\
|
||||
\"nfNamingCode\": \"@nfNamingCode@\",\
|
||||
\"nfVendorName\": \"@nfVendorName@\",\
|
||||
\"timeZoneOffset\": \"+00:00\",\
|
||||
\"version\": \"4.1\",\
|
||||
\"vesEventListenerVersion\": \"7.2.1\",\
|
||||
\"stndDefinedNamespace\": \"@stndDefinedNamespace@\",\
|
||||
\"nfcNamingCode\": \"NFC\"\
|
||||
}"
|
||||
|
||||
#define VES_PNF_REGISTRATION_TEMPLATE "\"pnfRegistrationFields\": {\
|
||||
\"pnfRegistrationFieldsVersion\": \"2.1\",\
|
||||
\"lastServiceDate\": \"2021-03-26\",\
|
||||
\"macAddress\": \"@macAddress@\",\
|
||||
\"manufactureDate\": \"2021-01-16\",\
|
||||
\"modelNumber\": \"@model@\",\
|
||||
\"oamV4IpAddress\": \"@oamIp@\",\
|
||||
@ipv6FullDefine@\
|
||||
\"serialNumber\": \"@vendor@-@type@-@oamIp@-@model@\",\
|
||||
\"softwareVersion\": \"2.3.5\",\
|
||||
\"unitFamily\": \"@vendor@-@type@\",\
|
||||
\"unitType\": \"@type@\",\
|
||||
\"vendorName\": \"@vendor@\",\
|
||||
\"additionalFields\": {\
|
||||
\"oamPort\": \"@port@\",\
|
||||
\"protocol\": \"SSH\",\
|
||||
\"username\": \"@username@\",\
|
||||
\"password\": \"@password@\",\
|
||||
\"reconnectOnChangedSchema\": \"false\",\
|
||||
\"sleep-factor\": \"1.5\",\
|
||||
\"tcpOnly\": \"false\",\
|
||||
\"connectionTimeout\": \"20000\",\
|
||||
\"maxConnectionAttempts\": \"100\",\
|
||||
\"betweenAttemptsTimeout\": \"2000\",\
|
||||
\"keepaliveDelay\": \"120\"\
|
||||
}\
|
||||
}"
|
||||
|
||||
#define VES_PNF_ALARMING_TEMPLATE_RAISE "\"stndDefinedFields\": {\
|
||||
\"schemaReference\": \"https://forge.3gpp.org/rep/sa5/MnS/raw/Rel-18/OpenAPI/TS28532_FaultMnS.yaml#components/schemas/NotifyNewAlarm\",\
|
||||
\"data\": {\
|
||||
\"href\": \"href1\",\
|
||||
\"notificationId\": @seqId@,\
|
||||
\"notificationType\": \"notifyNewAlarm\",\
|
||||
\"eventTime\": \"@eventTime@\",\
|
||||
\"systemDN\": \"xyz\",\
|
||||
\"alarmId\": \"@alarm@\",\
|
||||
\"alarmType\": \"COMMUNICATIONS_ALARM\",\
|
||||
\"probableCause\": \"@alarm@\",\
|
||||
\"specificProblem\": \"@alarm@\",\
|
||||
\"perceivedSeverity\": \"@severity@\",\
|
||||
\"backedUpStatus\": true,\
|
||||
\"backUpObject\": \"xyz\",\
|
||||
\"trendIndication\": \"MORE_SEVERE\",\
|
||||
\"thresholdInfo\": {\
|
||||
\"observedMeasurement\": \"new\",\
|
||||
\"observedValue\": 123.1\
|
||||
},\
|
||||
\"correlatedNotifications\": [],\
|
||||
\"stateChangeDefinition\": [{ \"operational-state\": \"DISABLED\" }],\
|
||||
\"monitoredAttributes\": {\
|
||||
\"interface\": \"@interface@\"\
|
||||
},\
|
||||
\"proposedRepairActions\": \"Call the police!\",\
|
||||
\"additionalText\": \"O-RAN Software Community OAM\",\
|
||||
\"additionalInformation\": {\
|
||||
\"eventTime\": \"@eventTime@\",\
|
||||
\"equipType\": \"@type@\",\
|
||||
\"vendor\": \"@vendor@\",\
|
||||
\"model\": \"@model@\"\
|
||||
},\
|
||||
\"rootCauseIndicator\": false\
|
||||
},\
|
||||
\"stndDefinedFieldsVersion\": \"1.0\"\
|
||||
}"
|
||||
|
||||
#define VES_PNF_ALARMING_TEMPLATE_CLEAR "\"stndDefinedFields\": {\
|
||||
\"schemaReference\": \"https://forge.3gpp.org/rep/sa5/MnS/raw/Rel-18/OpenAPI/TS28532_FaultMnS.yaml#components/schemas/NotifyClearedAlarm\",\
|
||||
\"data\": {\
|
||||
\"href\": \"href1\",\
|
||||
\"notificationId\": @seqId@,\
|
||||
\"notificationType\": \"notifyNewAlarm\",\
|
||||
\"eventTime\": \"@eventTime@\",\
|
||||
\"systemDN\": \"xyz\",\
|
||||
\"alarmId\": \"@alarm@\",\
|
||||
\"alarmType\": \"COMMUNICATIONS_ALARM\",\
|
||||
\"probableCause\": \"@alarm@\",\
|
||||
\"perceivedSeverity\": \"@severity@\",\
|
||||
\"clearUserId\": \"@vendor@\",\
|
||||
\"clearSystemId\": \"@vendor@\"\
|
||||
},\
|
||||
\"stndDefinedFieldsVersion\": \"1.0\"\
|
||||
}"
|
||||
|
||||
#define VES_FILE_READY_TEMPLATE "\"stndDefinedFields\": {\
|
||||
\"schemaReference\": \"https://forge.3gpp.org/rep/sa5/MnS/raw/Rel-18/OpenAPI/TS28532_FileDataReportingMnS.yaml#components/schemas/NotifyFileReady\",\
|
||||
\"data\": {\
|
||||
\"href\": \"href1\",\
|
||||
\"notificationId\": 0,\
|
||||
\"notificationType\": \"notifyFileReady\",\
|
||||
\"eventTime\": \"@eventTime@\",\
|
||||
\"systemDN\": \"xyz\",\
|
||||
\"fileInfoList\": [{\
|
||||
\"fileLocation\": \"@fileLocation@\",\
|
||||
\"fileSize\": @fileSize@,\
|
||||
\"fileReadyTime\": \"@eventTime@\",\
|
||||
\"fileExpirationTime\": \"@expTime@\",\
|
||||
\"fileCompression\": \"no\",\
|
||||
\"fileFormat\": \"xml\",\
|
||||
\"fileDataType\": \"Performance\"\
|
||||
}],\
|
||||
\"additionalText\": \"Have fun!\"\
|
||||
},\
|
||||
\"stndDefinedFieldsVersion\": \"1.0\"\
|
||||
}"
|
||||
|
||||
/*
|
||||
#define VES_FILE_READY_TEMPLATE "\"notificationFields\": {\
|
||||
\"changeIdentifier\": \"PM_MEAS_FILES\",\
|
||||
\"changeType\": \"FileReady\",\
|
||||
\"notificationFieldsVersion\": \"2.0\",\
|
||||
\"arrayOfNamedHashMap\": [\
|
||||
{\
|
||||
\"name\": \"@filename@\",\
|
||||
\"hashMap\": {\
|
||||
\"location\": \"@fileLocation@\",\
|
||||
\"compression\": \"gzip\",\
|
||||
\"fileFormatType\": \"org.3GPP.32.435#measCollec\",\
|
||||
\"fileFormatVersion\": \"V5\"\
|
||||
}\
|
||||
}\
|
||||
]\
|
||||
}"
|
||||
*/
|
||||
|
||||
struct memory {
|
||||
char *response;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static int ves_execute(char *priority, char *domain, char *event_type, char *stnd_defined_namespace, char* main_content);
|
||||
static int ves_http_request(const char *url, const char *username, const char* password, const char *method, const char *send_data, int *response_code, char **recv_data);
|
||||
static size_t curl_write_cb(void *data, size_t size, size_t nmemb, void *userp);
|
||||
static int vsftp_daemon_init(void);
|
||||
static int vsftp_daemon_deinit(void);
|
||||
static int sftp_daemon_init(void);
|
||||
static int sftp_daemon_deinit(void);
|
||||
|
||||
|
||||
static ves_config_t ves_config = {0};
|
||||
static int ves_seq_id = 0;
|
||||
static char *ves_common_header = 0;
|
||||
|
||||
|
||||
/**
|
||||
* initialize ves component
|
||||
* save config internally
|
||||
* prepare ves common header as far as possible
|
||||
*/
|
||||
int ves_init(ves_config_t *config, ves_header_t *ves) {
|
||||
if(ves_common_header) {
|
||||
netconf_log_error("ves_init() already called");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ves_common_header = strdup(VES_COMMON_HEADER_TEMPLATE);
|
||||
if(ves_common_header == 0) {
|
||||
netconf_log_error("strdup() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ves_config.url = strdup(config->url);
|
||||
ves_config.username = strdup(config->username);
|
||||
ves_config.password = strdup(config->password);
|
||||
if(!ves_config.url || !ves_config.username || !ves_config.password) {
|
||||
netconf_log_error("strdup() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ves_common_header = str_replace_inplace(ves_common_header, "@controllerName@", ves->hostname);
|
||||
if(ves_common_header == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ves_common_header = str_replace_inplace(ves_common_header, "@pnfId@", ves->pnf_id);
|
||||
if(ves_common_header == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ves_common_header = str_replace_inplace(ves_common_header, "@nfNamingCode@", ves->nf_naming_code);
|
||||
if(ves_common_header == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ves_common_header = str_replace_inplace(ves_common_header, "@nfVendorName@", ves->nf_vendor_name);
|
||||
if(ves_common_header == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
int rc = vsftp_daemon_init();
|
||||
if(rc != 0) {
|
||||
netconf_log_error("vsftp_daemon_init() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// rc = sftp_daemon_init();
|
||||
// if(rc != 0) {
|
||||
// netconf_log_error("sftp_daemon_init() failed");
|
||||
// goto failed;
|
||||
// }
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
ves_free();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ves_free() {
|
||||
vsftp_daemon_deinit();
|
||||
// sftp_daemon_deinit();
|
||||
|
||||
free(ves_common_header);
|
||||
free(ves_config.url);
|
||||
free(ves_config.username);
|
||||
free(ves_config.password);
|
||||
|
||||
ves_seq_id = 0;
|
||||
ves_common_header = 0;
|
||||
memset(&ves_config, 0, sizeof(ves_config_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* send ves pnfRegistration
|
||||
*
|
||||
*/
|
||||
int ves_pnf_registration_execute(ves_registration_data_t *ves) {
|
||||
char *content = strdup(VES_PNF_REGISTRATION_TEMPLATE);
|
||||
if(content == 0) {
|
||||
netconf_log_error("strdup() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
char *port = 0;
|
||||
asprintf(&port, "%d",ves->pnf_port);
|
||||
if(port == 0) {
|
||||
netconf_log_error("asprintf() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// fill template
|
||||
content = str_replace_inplace(content, "@macAddress@", ves->mac_address);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@model@", ves->model);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@oamIp@", ves->pnf_ip_v4_address);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
char *ipv6 = strdup("");
|
||||
if(ipv6 == 0) {
|
||||
netconf_log_error("strdup() failed");
|
||||
goto failed;
|
||||
}
|
||||
if(ves->pnf_ip_v6_address && strlen(ves->pnf_ip_v6_address)) {
|
||||
free(ipv6);
|
||||
asprintf(&ipv6, "\"oamV6IpAddress\": \"%s\"", ves->pnf_ip_v6_address);
|
||||
if(ipv6 == 0) {
|
||||
netconf_log_error("asprintf() failed");
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
content = str_replace_inplace(content, "@ipv6FullDefine@", ipv6);
|
||||
free(ipv6);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@vendor@", ves->vendor);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@type@", ves->type);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@port@", port);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@username@", ves->pnf_username);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@password@", ves->pnf_password);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
int rc = ves_execute(PRIORITY_PNFREGISTRATION, DOMAIN_PNFREGISTRAION, EVENTTYPE_PNFREGISTRATION,
|
||||
STNDDEF_NAMESPACE_NONE, content);
|
||||
if(rc != 0) {
|
||||
netconf_log_error("ves_execute() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
free(port);
|
||||
free(content);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
free(port);
|
||||
free(content);
|
||||
return 1;
|
||||
}
|
||||
/**
|
||||
* send ves pnf file ready event
|
||||
*
|
||||
*/
|
||||
int ves_pnf_pmdata_fileready_execute(ves_file_ready_t* ves_data) {
|
||||
char *content = strdup(VES_FILE_READY_TEMPLATE);
|
||||
if(content == 0) {
|
||||
netconf_log_error("strdup() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
char *filesize = 0;
|
||||
asprintf(&filesize, "%lu", ves_data->filesize);
|
||||
if(filesize == 0) {
|
||||
netconf_log_error("asprintf() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// fill template
|
||||
content = str_replace_inplace(content, "@expTime@", ves_data->expires_on);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@fileLocation@", ves_data->filelocation);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@fileSize@", filesize);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
int rc = ves_execute(PRIORITY_PMDATA, DOMAIN_PMDATA, EVENTTYPE_PNFALARMING,
|
||||
STNDDEF_NAMESPACE_NONE, content);
|
||||
if(rc != 0) {
|
||||
netconf_log_error("ves_execute() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
free(filesize);
|
||||
free(content);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
free(filesize);
|
||||
free(content);
|
||||
return 1;
|
||||
}
|
||||
/**
|
||||
* send ves pnf alarm
|
||||
*
|
||||
*/
|
||||
int ves_pnf_alarm_execute(ves_alarm_t* ves_alarm) {
|
||||
char *content;
|
||||
char *timestamp = 0;
|
||||
char *seq_id = 0;
|
||||
|
||||
if (strcmp(VES_ALARM_ALARMTYPE_NONALARM, ves_alarm->alarm_type) == 0) {
|
||||
content = strdup(VES_PNF_ALARMING_TEMPLATE_CLEAR);
|
||||
}
|
||||
else {
|
||||
content = strdup(VES_PNF_ALARMING_TEMPLATE_RAISE);
|
||||
}
|
||||
|
||||
if(content == 0) {
|
||||
netconf_log_error("strdup() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// asprintf(×tamp, "%lu", get_microseconds_since_epoch());
|
||||
// if(timestamp == 0) {
|
||||
// netconf_log_error("asprintf() failed");
|
||||
// goto failed;
|
||||
// }
|
||||
timestamp = get_netconf_timestamp();
|
||||
|
||||
asprintf(&seq_id, "%d", ves_seq_id);
|
||||
if(seq_id == 0) {
|
||||
netconf_log_error("asprintf() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@eventTime@", timestamp);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@seqId@", seq_id);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@notificationId@", "");
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@alarm@", ves_alarm->alarm_name);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@severity@", ves_alarm->severity);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@type@", ves_alarm->alarm_type);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@vendor@", ves_alarm->vendor);
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
content = str_replace_inplace(content, "@model@", "");
|
||||
if(content == 0) {
|
||||
netconf_log_error("str_replace_inplace failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
int rc = ves_execute(PRIORITY_PNFALARMING, DOMAIN_STNDDEFINED, EVENTTYPE_PNFALARMING,
|
||||
STNDDEF_NAMESPACE_FAULT, content);
|
||||
if(rc != 0) {
|
||||
netconf_log_error("ves_execute() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
free(content);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
free(content);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ves_execute(char *priority, char *domain, char *event_type, char *stnd_defined_namespace, char* main_content) {
|
||||
char *timestamp = 0;
|
||||
char *seq_id = 0;
|
||||
char *post_data = 0;
|
||||
char *header = 0;
|
||||
|
||||
asprintf(×tamp, "%lu", get_microseconds_since_epoch());
|
||||
if(timestamp == 0) {
|
||||
netconf_log_error("asprintf() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
asprintf(&seq_id, "%d", ves_seq_id);
|
||||
if(seq_id == 0) {
|
||||
netconf_log_error("asprintf() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
//fill header
|
||||
header = strdup(ves_common_header);
|
||||
if(header == 0) {
|
||||
netconf_log_error("strdup() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
header = str_replace_inplace(header, "@seqId@", seq_id);
|
||||
if(header == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
header = str_replace_inplace(header, "@timestamp@", timestamp);
|
||||
if(header == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
header = str_replace_inplace(header, "@priority@", priority);
|
||||
if(header == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
header = str_replace_inplace(header, "@domain@", domain);
|
||||
if(header == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
header = str_replace_inplace(header, "@eventType@", event_type);
|
||||
if(header == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
header = str_replace_inplace(header, "@stndDefinedNamespace@", stnd_defined_namespace);
|
||||
if(header == 0) {
|
||||
netconf_log_error("str_replace_inplace() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
//append body
|
||||
asprintf(&post_data,"{\"event\":{%s,%s}}", header, main_content);
|
||||
if(post_data == 0) {
|
||||
netconf_log_error("asprintf() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
//send request
|
||||
int response_code;
|
||||
char *response = 0;
|
||||
int rc = ves_http_request(ves_config.url, ves_config.username, ves_config.password, "POST", post_data, &response_code, &response);
|
||||
if(rc != 0) {
|
||||
netconf_log_error("ves_http_request() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
netconf_log("response_code = %d", response_code);
|
||||
if(response) {
|
||||
netconf_log("response = %s", response);
|
||||
}
|
||||
|
||||
free(response);
|
||||
if(response_code > 399) {
|
||||
netconf_log_error("failure http response code: %d", response_code);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
ves_seq_id++;
|
||||
free(timestamp);
|
||||
free(seq_id);
|
||||
free(post_data);
|
||||
free(header);
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
free(timestamp);
|
||||
free(seq_id);
|
||||
free(post_data);
|
||||
free(header);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ves_http_request(const char *url, const char *username, const char* password, const char *method, const char *send_data, int *response_code, char **recv_data) {
|
||||
const char *send_data_good = send_data;
|
||||
if(send_data_good == 0) {
|
||||
send_data_good = "";
|
||||
}
|
||||
|
||||
CURL *curl = curl_easy_init();
|
||||
if(curl == 0) {
|
||||
netconf_log_error("curl_easy_init() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// set curl options
|
||||
struct curl_slist *header = 0;
|
||||
header = curl_slist_append(header, "Content-Type: application/json");
|
||||
if(!header) {
|
||||
netconf_log_error("curl_slist_append() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
header = curl_slist_append(header, "Accept: application/json");
|
||||
if(!header) {
|
||||
netconf_log_error("curl_slist_append() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
header = curl_slist_append(header, "X-MinorVersion: 1");
|
||||
if(!header) {
|
||||
netconf_log_error("curl_slist_append() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
CURLcode res = CURLE_OK;
|
||||
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 1L); //seconds timeout for a connection
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1L); //seconds timeout for an operation
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1L);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
// disable SSL verifications
|
||||
res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, send_data_good);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
char *credentials = 0;
|
||||
if((username) && (password)) {
|
||||
asprintf(&credentials, "%s:%s", username, password);
|
||||
if(credentials == 0) {
|
||||
netconf_log_error("asprintf() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_USERPWD, credentials);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
struct memory response_data = {0};
|
||||
if(recv_data) {
|
||||
res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response_data);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_setopt() error");
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
netconf_log("%s-ing cURL to url=\"%s\" with body=\"%s\"... ", method, url, send_data_good);
|
||||
res = curl_easy_perform(curl);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_perform() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if(response_code) {
|
||||
long http_rc;
|
||||
res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_rc);
|
||||
if(res != CURLE_OK) {
|
||||
netconf_log_error("curl_easy_getinfo() failed");
|
||||
goto failed;
|
||||
}
|
||||
*response_code = http_rc;
|
||||
}
|
||||
|
||||
if(recv_data) {
|
||||
*recv_data = response_data.response;
|
||||
}
|
||||
|
||||
free(credentials);
|
||||
curl_slist_free_all(header);
|
||||
curl_easy_cleanup(curl);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
free(credentials);
|
||||
curl_slist_free_all(header);
|
||||
curl_easy_cleanup(curl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static size_t curl_write_cb(void *data, size_t size, size_t nmemb, void *userp) {
|
||||
size_t realsize = size * nmemb;
|
||||
struct memory *mem = (struct memory *)userp;
|
||||
|
||||
char *ptr = realloc(mem->response, mem->size + realsize + 1);
|
||||
if(ptr == NULL) {
|
||||
//TODO log_error("realloc failed\n");
|
||||
return 0; /* out of memory! */
|
||||
}
|
||||
|
||||
mem->response = ptr;
|
||||
memcpy(&(mem->response[mem->size]), data, realsize);
|
||||
mem->size += realsize;
|
||||
mem->response[mem->size] = 0;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
static int vsftp_daemon_init(void) {
|
||||
return system("/usr/sbin/vsftpd &");
|
||||
}
|
||||
|
||||
static int vsftp_daemon_deinit(void) {
|
||||
return system("killall -9 vsftpd");
|
||||
}
|
||||
|
||||
static int sftp_daemon_init(void) {
|
||||
return system("/usr/sbin/sshd -D &");
|
||||
}
|
||||
|
||||
static int sftp_daemon_deinit(void) {
|
||||
return system("killall -9 sshd");
|
||||
}
|
||||
77
common/utils/netconf/ves.h
Normal file
77
common/utils/netconf/ves.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// common data
|
||||
typedef struct ves_header {
|
||||
char *hostname;
|
||||
char *nf_naming_code;
|
||||
char *nf_vendor_name;
|
||||
char *pnf_id;
|
||||
} ves_header_t;
|
||||
|
||||
// ves endpoint configuration
|
||||
typedef struct ves_config {
|
||||
char *url; // endpoint url e.g. https://10.20.30.40/enventlistener/v7
|
||||
char *username; // basic auth username
|
||||
char *password; // basic auth password
|
||||
} ves_config_t;
|
||||
|
||||
//pnfRegistration data
|
||||
typedef struct ves_registration_data {
|
||||
char *pnf_username;
|
||||
char *pnf_password;
|
||||
char *pnf_ip_v4_address;
|
||||
char *pnf_ip_v6_address;
|
||||
int pnf_port;
|
||||
char *mac_address;
|
||||
char *vendor;
|
||||
char *model;
|
||||
char *type;
|
||||
bool is_tls;
|
||||
} ves_registration_data_t;
|
||||
|
||||
//
|
||||
typedef struct ves_file_ready {
|
||||
char *filename;
|
||||
char *filelocation;
|
||||
unsigned long int filesize;
|
||||
char *expires_on;
|
||||
} ves_file_ready_t;
|
||||
|
||||
//
|
||||
typedef struct ves_alarm {
|
||||
char *alarm_name;
|
||||
char *severity;
|
||||
char *alarm_type; //TODO: maybe we should think about enum
|
||||
char *vendor;
|
||||
char *model;
|
||||
} ves_alarm_t;
|
||||
|
||||
|
||||
#define DOMAIN_PNFREGISTRAION "pnfRegistration"
|
||||
#define DOMAIN_PNFALARMING "fault"
|
||||
#define DOMAIN_HEARTBEAT "heartbeat"
|
||||
#define DOMAIN_PMDATA "measurement"
|
||||
#define DOMAIN_STNDDEFINED "stndDefined"
|
||||
#define EVENTTYPE_PNFREGISTRATION "EventType5G"
|
||||
#define EVENTTYPE_PNFALARMING "O_RAN_COMPONENT_Alarms"
|
||||
#define EVENTTYPE_PMDATA "Notification-gnb_Nokia-FileReady"
|
||||
#define PRIORITY_PNFREGISTRATION "Low"
|
||||
#define PRIORITY_PNFALARMING "Low"
|
||||
#define PRIORITY_PMDATA "Low"
|
||||
#define STNDDEF_NAMESPACE_FAULT "3GPP-FaultSupervision"
|
||||
#define STNDDEF_NAMESPACE_NONE ""
|
||||
|
||||
#define VES_ALARM_SEVERITY_CLEARED "CLEARED"
|
||||
#define VES_ALARM_ALARMTYPE_ALARM "ALARM"
|
||||
#define VES_ALARM_ALARMTYPE_NONALARM "NON-ALARM"
|
||||
|
||||
|
||||
|
||||
int ves_init(ves_config_t *config, ves_header_t *header);
|
||||
void ves_free();
|
||||
|
||||
int ves_pnf_registration_execute(ves_registration_data_t *data);
|
||||
int ves_pnf_pmdata_fileready_execute(ves_file_ready_t* ves_data);
|
||||
int ves_pnf_alarm_execute(ves_alarm_t* ves_alarm);
|
||||
76
common/utils/netconf/ves_demo_alarm.c
Normal file
76
common/utils/netconf/ves_demo_alarm.c
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "ves_demo_alarm.h"
|
||||
#include "netconf_log.h"
|
||||
#include "o1config.h"
|
||||
#include "ves.h"
|
||||
#include <pthread.h>
|
||||
|
||||
typedef struct ves_demo_alarm_params {
|
||||
int interval;
|
||||
} ves_demo_alarm_params_t;
|
||||
|
||||
static pthread_t ves_demo_alarm_thread;
|
||||
|
||||
static void *ves_demo_alarm_routine(void *arg);
|
||||
|
||||
int ves_demo_alarm_start(o1_config_t *config) {
|
||||
ves_demo_alarm_params_t *params = (ves_demo_alarm_params_t *)malloc(sizeof(ves_demo_alarm_params_t));
|
||||
if(params == 0) {
|
||||
netconf_log_error("malloc failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
params->interval = config->demo_alarming_interval;
|
||||
|
||||
|
||||
int rc = pthread_create(&ves_demo_alarm_thread, 0, ves_demo_alarm_routine, params);
|
||||
if(rc != 0) {
|
||||
netconf_log_error("pthread_create() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
free(params);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *ves_demo_alarm_routine(void *arg) {
|
||||
ves_demo_alarm_params_t *params = (ves_demo_alarm_params_t *)arg;
|
||||
|
||||
int alarm_type = 0;
|
||||
while(1) {
|
||||
sleep(params->interval);
|
||||
alarm_type++;
|
||||
if(alarm_type >= 2) {
|
||||
alarm_type = 0;
|
||||
}
|
||||
|
||||
ves_alarm_t alarm = {
|
||||
.alarm_name = "demoAlarm",
|
||||
.vendor = "highstreet",
|
||||
.model = "oai"
|
||||
};
|
||||
if(alarm_type) {
|
||||
netconf_log("set alarm");
|
||||
alarm.severity = "MAJOR";
|
||||
alarm.alarm_type = VES_ALARM_ALARMTYPE_ALARM;
|
||||
}
|
||||
else {
|
||||
netconf_log("clear alarm");
|
||||
alarm.severity = VES_ALARM_SEVERITY_CLEARED;
|
||||
alarm.alarm_type = VES_ALARM_ALARMTYPE_NONALARM;
|
||||
}
|
||||
|
||||
|
||||
netconf_log("alarm");
|
||||
int rc = ves_pnf_alarm_execute(&alarm);
|
||||
if(rc != 0) {
|
||||
netconf_log_error("ves_pnf_alarm_execute() failed");
|
||||
}
|
||||
}
|
||||
|
||||
free(arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
5
common/utils/netconf/ves_demo_alarm.h
Normal file
5
common/utils/netconf/ves_demo_alarm.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "o1config.h"
|
||||
|
||||
int ves_demo_alarm_start(o1_config_t *config);
|
||||
@@ -37,7 +37,9 @@
|
||||
#include "assertions.h"
|
||||
#include "PHY/defs_common.h"
|
||||
|
||||
#define MAX_BWP_SIZE 275
|
||||
#define MAX_BWP_SIZE 275
|
||||
#define NR_MAX_NUM_BWP 4
|
||||
#define NR_MAX_HARQ_PROCESSES 16
|
||||
|
||||
typedef struct nr_bandentry_s {
|
||||
int16_t band;
|
||||
@@ -82,7 +84,7 @@ int get_dmrs_port(int nl, uint16_t dmrs_ports);
|
||||
uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols);
|
||||
int get_nb_periods_per_frame(uint8_t tdd_period);
|
||||
int get_supported_band_index(int scs, int band, int n_rbs);
|
||||
long rrc_get_max_nr_csrs(uint8_t max_rbs, long b_SRS);
|
||||
long rrc_get_max_nr_csrs(const int max_rbs, long b_SRS);
|
||||
void get_samplerate_and_bw(int mu,
|
||||
int n_rb,
|
||||
int8_t threequarter_fs,
|
||||
|
||||
@@ -71,12 +71,11 @@ static inline uint16_t BIT_STRING_to_uint16(BIT_STRING_t *asn) {
|
||||
*/
|
||||
static inline uint32_t BIT_STRING_to_uint32(BIT_STRING_t *asn) {
|
||||
uint32_t result = 0;
|
||||
int index;
|
||||
int shift;
|
||||
size_t index;
|
||||
|
||||
DevCheck ((asn->size > 0) && (asn->size <= 4), asn->size, 0, 0);
|
||||
|
||||
shift = ((asn->size - 1) * 8) - asn->bits_unused;
|
||||
int shift = ((asn->size - 1) * 8) - asn->bits_unused;
|
||||
for (index = 0; index < (asn->size - 1); index++) {
|
||||
result |= asn->buf[index] << shift;
|
||||
shift -= 8;
|
||||
@@ -94,7 +93,7 @@ static inline uint32_t BIT_STRING_to_uint32(BIT_STRING_t *asn) {
|
||||
*/
|
||||
static inline uint64_t BIT_STRING_to_uint64(BIT_STRING_t *asn) {
|
||||
uint64_t result = 0;
|
||||
int index;
|
||||
size_t index;
|
||||
int shift;
|
||||
|
||||
DevCheck ((asn->size > 0) && (asn->size <= 8), asn->size, 0, 0);
|
||||
@@ -110,4 +109,13 @@ static inline uint64_t BIT_STRING_to_uint64(BIT_STRING_t *asn) {
|
||||
return result;
|
||||
}
|
||||
|
||||
#define asn1cSeqAdd(VaR, PtR) if (ASN_SEQUENCE_ADD(VaR,PtR)!=0) AssertFatal(false, "ASN.1 encoding error " #VaR "\n")
|
||||
#define asn1cCallocOne(VaR, VaLue) \
|
||||
VaR = calloc(1,sizeof(*VaR)); *VaR=VaLue
|
||||
#define asn1cCalloc(VaR, lOcPtr) \
|
||||
typeof(VaR) lOcPtr = VaR = calloc(1,sizeof(*VaR))
|
||||
#define asn1cSequenceAdd(VaR, TyPe, lOcPtr) \
|
||||
TyPe *lOcPtr= calloc(1,sizeof(TyPe)); \
|
||||
asn1cSeqAdd(&VaR,lOcPtr)
|
||||
|
||||
#endif
|
||||
@@ -366,9 +366,14 @@ void set_latency_target(void) {
|
||||
LOG_E(HW,"Can't set /dev/cpu_dma_latency to %u us\n", latency_target_value);
|
||||
|
||||
// Set CPU frequency to it's maximum
|
||||
if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
|
||||
LOG_E(HW,"Can't set cpu frequency\n");
|
||||
|
||||
int system_ret = system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done");
|
||||
if (system_ret == -1) {
|
||||
LOG_E(HW, "Can't set cpu frequency: [%d] %s\n", errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (!((WIFEXITED(system_ret)) && (WEXITSTATUS(system_ret) == 0))) {
|
||||
LOG_E(HW, "Can't set cpu frequency\n");
|
||||
}
|
||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
|
||||
}
|
||||
|
||||
@@ -165,8 +165,7 @@ void measurcmd_display_rlcstats(telnet_printfunc_t prnt) {
|
||||
statsptr[i].vptr = rlcstats + i;
|
||||
}
|
||||
|
||||
for (int UE_id=UE_info->list.head; UE_id>=0; UE_id=UE_info->list.next[UE_id]) {
|
||||
#define NB_eNB_INST 1
|
||||
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt,eNB_id, ENB_FLAG_YES,UE_info->eNB_UE_stats[0][UE_id].crnti,
|
||||
eNB->frame,eNB->subframe,eNB_id);
|
||||
measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DCCH", &ctxt, SRB_FLAG_YES, DCCH);
|
||||
|
||||
11
doc/Doxyfile
11
doc/Doxyfile
@@ -888,6 +888,7 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/config/libconfig/config_libconfig.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/config/libconfig/config_libconfig_private.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/config/config_userapi.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/oai_asn1.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/time_meas.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/backtrace.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/time_stat.h \
|
||||
@@ -930,7 +931,7 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/load_module_shlib.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/backtrace.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/assertions.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/asn1_conversions.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/oai_asn1.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/threadPool/thread-pool.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/threadPool/thread-pool.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/T/T.c \
|
||||
@@ -1248,7 +1249,7 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/rlc_v2/rlc_entity_am.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/rlc_v2/rlc_sdu.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/rlc_v2/rlc_entity.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/rlc_v2/asn1_utils.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/rlc_v2/rlc_asn1_utils.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/rlc_v2/rlc_ue_manager.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/rlc_v2/rlc_oai_api.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/rlc_v2/rlc_sdu.h \
|
||||
@@ -1356,7 +1357,7 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/asn1_utils.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_asn1_utils.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/asn1_utils.c \
|
||||
@@ -1390,7 +1391,7 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_rlc/nr_rlc_entity.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_rlc/nr_rlc_pdu.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_rlc/nr_rlc_sdu.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_rlc/asn1_utils.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_rlc/nr_rlc_asn1_utils.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_rlc/nr_rlc_pdu.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_rlc/asn1_utils.c \
|
||||
@@ -2109,7 +2110,6 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED/nfapi_lte_dummy.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED/sched_eNB.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED/phy_procedures_lte_common.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED/sched_common_vars.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED/phy_procedures_lte_eNb.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED/sched_common_extern.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED/nfapi_nr_dummy.c \
|
||||
@@ -2437,7 +2437,6 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/MODULATION/nr_modulation.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/MODULATION/slot_fep.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/MODULATION/ul_7_5_kHz.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/MODULATION/modulation_vars.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/MODULATION/slot_fep_ul.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/phy_extern.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/defs_UE.h \
|
||||
|
||||
@@ -42,6 +42,12 @@ RUN apt-get update && \
|
||||
psmisc \
|
||||
git \
|
||||
xxd \
|
||||
# libyang dependencies
|
||||
libpcre2-dev \
|
||||
# libssh dependencies
|
||||
zlib1g-dev libssl-dev \
|
||||
# netconf base dependencies
|
||||
unzip openssl openssh-client \
|
||||
# python3-pip for conf template generation
|
||||
python3-pip && \
|
||||
pip3 install --ignore-installed pyyaml
|
||||
|
||||
76
docker/Dockerfile.base.ubuntu22
Normal file
76
docker/Dockerfile.base.ubuntu22
Normal file
@@ -0,0 +1,76 @@
|
||||
#/*
|
||||
# * 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
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
#
|
||||
# Dockerfile for the Open-Air-Interface BUILD service
|
||||
# Valid for Ubuntu 18.04
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
|
||||
FROM ubuntu:22.04 AS ran-base
|
||||
ARG NEEDED_GIT_PROXY
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Europe/Paris
|
||||
ENV BUILD_UHD_FROM_SOURCE=True
|
||||
ENV UHD_VERSION=4.3.0.0
|
||||
|
||||
|
||||
RUN \
|
||||
apt-get clean && \
|
||||
cd /var/lib/apt && \
|
||||
mv lists lists.old && \
|
||||
mkdir -p lists/partial && \
|
||||
apt-get clean
|
||||
|
||||
#install developers pkg/repo
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
|
||||
#gcc needed for build_oai
|
||||
build-essential \
|
||||
psmisc \
|
||||
git \
|
||||
xxd \
|
||||
# libyang dependencies
|
||||
libpcre2-dev \
|
||||
# libssh dependencies
|
||||
zlib1g-dev libssl-dev \
|
||||
# netconf base dependencies
|
||||
unzip openssl openssh-client \
|
||||
# python3-pip for conf template generation
|
||||
python3-pip && \
|
||||
pip3 install --ignore-installed pyyaml
|
||||
|
||||
# In some network environments, GIT proxy is required
|
||||
RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi"
|
||||
|
||||
#create the WORKDIR
|
||||
WORKDIR /oai-ran
|
||||
COPY . .
|
||||
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libulfius-dev
|
||||
|
||||
#run build_oai -I to get the builder image
|
||||
RUN /bin/sh oaienv && \
|
||||
cd cmake_targets && \
|
||||
mkdir -p log && \
|
||||
./build_oai -I -w USRP
|
||||
@@ -27,12 +27,24 @@
|
||||
|
||||
FROM ran-base:latest as ran-build
|
||||
|
||||
# run dependencies install for netconf
|
||||
RUN ./docker/scripts/netconf_dep_install.sh
|
||||
|
||||
RUN rm -Rf /oai-ran
|
||||
WORKDIR /oai-ran
|
||||
COPY . .
|
||||
|
||||
# get and install required YANG libraries
|
||||
RUN \
|
||||
cd /oai-ran/specification && \
|
||||
./get-yangs.sh && \
|
||||
./install-yangs.sh
|
||||
|
||||
WORKDIR /oai-ran
|
||||
|
||||
# build all targets so final targets can be created afterwards
|
||||
RUN /bin/sh oaienv && \
|
||||
cd cmake_targets && \
|
||||
mkdir -p log && \
|
||||
./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci --noavx512 -c
|
||||
# ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci --noavx512 -c
|
||||
./build_oai --gNB -w USRP --build-lib telnetsrv --verbose-ci --noavx512 -c
|
||||
|
||||
53
ci-scripts/destroyAllRunningVM.sh → docker/Dockerfile.build.ubuntu22
Executable file → Normal file
53
ci-scripts/destroyAllRunningVM.sh → docker/Dockerfile.build.ubuntu22
Executable file → Normal file
@@ -1,4 +1,3 @@
|
||||
#!/bin/bash
|
||||
#/*
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
@@ -19,33 +18,33 @@
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
#
|
||||
# Dockerfile for the Open-Air-Interface BUILD service
|
||||
# Valid for Ubuntu 18.04
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
ARG BASETAG="latest"
|
||||
FROM ran-base:${BASETAG} as ran-build
|
||||
|
||||
function destroy_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo " Requirements:"
|
||||
echo " -- uvtool uvtool-libvirt apt-cacher"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo " oai-ci-vm-tool destroy [OPTIONS]"
|
||||
echo ""
|
||||
command_options_usage
|
||||
}
|
||||
# run dependencies install for netconf
|
||||
RUN ./docker/scripts/netconf_dep_install.sh
|
||||
|
||||
function destroy_vm {
|
||||
echo "############################################################"
|
||||
echo "OAI CI VM script"
|
||||
echo "############################################################"
|
||||
echo "VM_TEMPLATE = $VM_TEMPLATE"
|
||||
RUN rm -Rf /oai-ran
|
||||
WORKDIR /oai-ran
|
||||
COPY . .
|
||||
|
||||
LIST_CI_VM=`uvt-kvm list | grep $VM_TEMPLATE`
|
||||
# get and install required YANG libraries
|
||||
RUN \
|
||||
cd /oai-ran/specification && \
|
||||
./get-yangs.sh && \
|
||||
./install-yangs.sh
|
||||
|
||||
for CI_VM in $LIST_CI_VM
|
||||
do
|
||||
VM_IP_ADDR=`uvt-kvm ip $CI_VM`
|
||||
echo "VM to destroy: $CI_VM -- IP $VM_IP_ADDR"
|
||||
uvt-kvm destroy $CI_VM
|
||||
ssh-keygen -R $VM_IP_ADDR
|
||||
done
|
||||
}
|
||||
WORKDIR /oai-ran
|
||||
|
||||
# build all targets so final targets can be created afterwards
|
||||
RUN /bin/sh oaienv && \
|
||||
cd cmake_targets && \
|
||||
mkdir -p log && \
|
||||
# ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci --noavx512 -c
|
||||
./build_oai --gNB -w USRP --build-lib telnetsrv --verbose-ci --noavx512 -c
|
||||
75
docker/Dockerfile.dev.ubuntu18
Normal file
75
docker/Dockerfile.dev.ubuntu18
Normal file
@@ -0,0 +1,75 @@
|
||||
#/*
|
||||
# * 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
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
#
|
||||
# Dockerfile for the Open-Air-Interface BUILD service
|
||||
# Valid for Ubuntu 18.04
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
FROM ran-base:latest as ran-dev
|
||||
|
||||
# run dependencies install for netconf
|
||||
RUN ./docker/scripts/netconf_dep_install.sh
|
||||
|
||||
RUN rm -Rf /oai-ran
|
||||
WORKDIR /oai-ran
|
||||
COPY . .
|
||||
|
||||
# get and install required YANG libraries
|
||||
RUN \
|
||||
cd /oai-ran/specification && \
|
||||
./get-yangs.sh && \
|
||||
./install-yangs.sh
|
||||
|
||||
WORKDIR /oai-ran
|
||||
|
||||
# build all targets so final targets can be created afterwards
|
||||
RUN /bin/sh oaienv && \
|
||||
cd cmake_targets && \
|
||||
mkdir -p log
|
||||
# ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci --noavx512 -c
|
||||
# ./build_oai --gNB -w USRP --build-lib telnetsrv --verbose-ci --noavx512 -c
|
||||
|
||||
# Add netconf user and configure access
|
||||
RUN \
|
||||
adduser netconf && \
|
||||
echo "netconf:netconf!" | chpasswd && \
|
||||
mkdir -p /home/netconf/.ssh
|
||||
|
||||
# # Initialize netopeer2
|
||||
RUN \
|
||||
/usr/local/share/netopeer2/merge_hostkey.sh && \
|
||||
/usr/local/share/netopeer2/merge_config.sh
|
||||
COPY docker/scripts/gnb_entrypoint.sh /opt/oai-gnb/bin/entrypoint.sh
|
||||
WORKDIR /opt/oai-gnb
|
||||
#EXPOSE 2152/udp # S1U, GTP/UDP
|
||||
#EXPOSE 22100/tcp # ?
|
||||
#EXPOSE 36412/udp # S1C, SCTP/UDP
|
||||
#EXPOSE 36422/udp # X2C, SCTP/UDP
|
||||
#EXPOSE 50000/udp # IF5 / ORI (control)
|
||||
#EXPOSE 50001/udp # IF5 / ECPRI (data)
|
||||
|
||||
# ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"]
|
||||
# CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"]
|
||||
|
||||
WORKDIR /oai-ran/cmake_targets
|
||||
CMD ["/bin/sh", "-c", "sleep infinity"]
|
||||
109
docker/Dockerfile.dev.ubuntu22
Normal file
109
docker/Dockerfile.dev.ubuntu22
Normal file
@@ -0,0 +1,109 @@
|
||||
#/*
|
||||
# * 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
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
#
|
||||
# Dockerfile for the Open-Air-Interface BUILD service
|
||||
# Valid for Ubuntu 18.04
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
ARG BASETAG="latest"
|
||||
FROM ran-build:${BASETAG} AS gnb-build
|
||||
|
||||
FROM ran-base:${BASETAG} as ran-dev
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install --yes \
|
||||
openssh-client \
|
||||
vsftpd
|
||||
|
||||
# run dependencies install for netconf
|
||||
RUN ./docker/scripts/netconf_dep_install.sh
|
||||
|
||||
RUN rm -Rf /oai-ran
|
||||
WORKDIR /oai-ran
|
||||
COPY . .
|
||||
|
||||
# get and install required YANG libraries
|
||||
RUN \
|
||||
cd /oai-ran/specification && \
|
||||
./get-yangs.sh && \
|
||||
./install-yangs.sh
|
||||
|
||||
WORKDIR /oai-ran
|
||||
|
||||
# build all targets so final targets can be created afterwards
|
||||
RUN /bin/sh oaienv && \
|
||||
cd cmake_targets && \
|
||||
mkdir -p log
|
||||
# ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci --noavx512 -c
|
||||
# ./build_oai --gNB -w USRP --build-lib telnetsrv --build-lib --verbose-ci --noavx512 -c
|
||||
|
||||
COPY --from=gnb-build \
|
||||
/oai-ran/cmake_targets/ran_build/build/liboai_eth_transpro.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/librfsimulator.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/liboai_usrpdevif.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libldpc.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
|
||||
/usr/local/lib/
|
||||
|
||||
# Add netconf user and configure access
|
||||
RUN \
|
||||
adduser netconf && \
|
||||
echo "netconf:netconf!" | chpasswd && \
|
||||
mkdir -p /home/netconf/.ssh
|
||||
|
||||
### FTP and SFTP configuration
|
||||
RUN \
|
||||
mkdir /ftp && \
|
||||
chown -R netconf:netconf /ftp && \
|
||||
mkdir /var/run/vsftpd && \
|
||||
mkdir /var/run/vsftpd/empty && \
|
||||
mkdir /run/sshd && \
|
||||
echo "Match User netconf\n ChrootDirectory /\n X11Forwarding no\n AllowTcpForwarding no\n ForceCommand internal-sftp -d /ftp" >> /etc/ssh/sshd_config
|
||||
|
||||
COPY docker/config/vsftpd.conf /etc/vsftpd.conf
|
||||
COPY docker/config/vsftpd.userlist /etc/vsftpd.userlist
|
||||
|
||||
# # Initialize netopeer2
|
||||
RUN \
|
||||
/usr/local/share/netopeer2/merge_hostkey.sh && \
|
||||
/usr/local/share/netopeer2/merge_config.sh
|
||||
COPY docker/scripts/gnb_entrypoint.sh /opt/oai-gnb/bin/entrypoint.sh
|
||||
WORKDIR /opt/oai-gnb
|
||||
#EXPOSE 2152/udp # S1U, GTP/UDP
|
||||
#EXPOSE 22100/tcp # ?
|
||||
#EXPOSE 36412/udp # S1C, SCTP/UDP
|
||||
#EXPOSE 36422/udp # X2C, SCTP/UDP
|
||||
#EXPOSE 50000/udp # IF5 / ORI (control)
|
||||
#EXPOSE 50001/udp # IF5 / ECPRI (data)
|
||||
|
||||
# ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"]
|
||||
# CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"]
|
||||
|
||||
WORKDIR /oai-ran/cmake_targets
|
||||
CMD ["/bin/sh", "-c", "sleep infinity"]
|
||||
@@ -58,7 +58,10 @@ RUN apt-get update && \
|
||||
python3 \
|
||||
python3-six \
|
||||
python3-requests \
|
||||
libusb-1.0-0 && \
|
||||
libusb-1.0-0 \
|
||||
# libyang/sysrepo/netopeer2
|
||||
libpcre2-8-0 \
|
||||
openssh-client && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /opt/oai-gnb/bin
|
||||
@@ -102,6 +105,43 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai
|
||||
WORKDIR /opt/oai-gnb/etc
|
||||
COPY --from=gnb-build /oai-ran/docker/etc .
|
||||
|
||||
# Copy relevant netopeer/sysrepo files for gNB
|
||||
COPY --from=gnb-build \
|
||||
/usr/local/bin/yanglint \
|
||||
/usr/local/bin/yangre \
|
||||
/usr/local/bin/sysrepo-plugind \
|
||||
/usr/local/bin/sysrepocfg \
|
||||
/usr/local/bin/sysrepoctl \
|
||||
/usr/local/bin/netopeer2-cli \
|
||||
/usr/local/bin/
|
||||
|
||||
COPY --from=gnb-build /usr/local/sbin/netopeer2-server /usr/local/sbin/netopeer2-server
|
||||
COPY --from=gnb-build \
|
||||
/usr/local/lib/libnetconf2.so \
|
||||
/usr/local/lib/libssh.so \
|
||||
/usr/local/lib/libsysrepo.so \
|
||||
/usr/local/lib/libyang.so \
|
||||
/usr/local/lib/sysrepo-plugind/ \
|
||||
/usr/local/lib/
|
||||
|
||||
RUN ldconfig
|
||||
|
||||
COPY --from=gnb-build /usr/local/share/yang /usr/local/share/yang
|
||||
COPY --from=gnb-build /usr/local/share/netopeer2 /usr/local/share/netopeer2
|
||||
COPY --from=gnb-build /etc/sysrepo /etc/sysrepo
|
||||
|
||||
|
||||
# Add netconf user and configure access
|
||||
RUN \
|
||||
adduser netconf && \
|
||||
echo "netconf:netconf!" | chpasswd && \
|
||||
mkdir -p /home/netconf/.ssh
|
||||
|
||||
# # Initialize netopeer2
|
||||
RUN \
|
||||
/usr/local/share/netopeer2/merge_hostkey.sh && \
|
||||
/usr/local/share/netopeer2/merge_config.sh
|
||||
COPY docker/scripts/gnb_entrypoint.sh /opt/oai-gnb/bin/entrypoint.sh
|
||||
WORKDIR /opt/oai-gnb
|
||||
#EXPOSE 2152/udp # S1U, GTP/UDP
|
||||
#EXPOSE 22100/tcp # ?
|
||||
|
||||
173
docker/Dockerfile.gNB.ubuntu22
Normal file
173
docker/Dockerfile.gNB.ubuntu22
Normal file
@@ -0,0 +1,173 @@
|
||||
#/*
|
||||
# * 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
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
#
|
||||
# Dockerfile for the Open-Air-Interface BUILD service
|
||||
# Valid for Ubuntu18.04
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
ARG BASETAG="latest"
|
||||
FROM ran-base:${BASETAG} as gnb-base
|
||||
|
||||
FROM ran-build:${BASETAG} AS gnb-build
|
||||
|
||||
RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/gnb_parameters.yaml && \
|
||||
cp /oai-ran/docker/scripts/gnb_entrypoint.sh /oai-ran/docker/scripts/entrypoint.sh
|
||||
|
||||
#start from scratch for target executable
|
||||
FROM ubuntu:22.04 as oai-gnb
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Europe
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
|
||||
software-properties-common \
|
||||
procps \
|
||||
libsctp1 \
|
||||
tzdata \
|
||||
libnettle8 \
|
||||
libblas3 \
|
||||
libatlas3-base \
|
||||
libconfig9 \
|
||||
openssl \
|
||||
net-tools \
|
||||
iperf \
|
||||
iproute2 \
|
||||
iputils-ping \
|
||||
gdb \
|
||||
python3 \
|
||||
python3-six \
|
||||
python3-requests \
|
||||
libusb-1.0-0 \
|
||||
# libyang/sysrepo/netopeer2
|
||||
psmisc \
|
||||
libpcre2-8-0 \
|
||||
openssh-client \
|
||||
vsftpd && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /opt/oai-gnb/bin
|
||||
COPY --from=gnb-build \
|
||||
/oai-ran/cmake_targets/ran_build/build/nr-softmodem \
|
||||
/oai-ran/docker/scripts/entrypoint.sh \
|
||||
./
|
||||
|
||||
COPY --from=gnb-build \
|
||||
/oai-ran/cmake_targets/ran_build/build/liboai_eth_transpro.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/librfsimulator.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/liboai_usrpdevif.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libldpc.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
|
||||
/usr/local/lib/
|
||||
|
||||
# Now we are copying from builder-image the UHD files.
|
||||
COPY --from=gnb-base /usr/local/bin/uhd_find_devices /usr/local/bin
|
||||
COPY --from=gnb-base /usr/local/lib/libuhd.so.4.3.0 /usr/local/lib
|
||||
COPY --from=gnb-base /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai-gnb/bin
|
||||
COPY --from=gnb-base \
|
||||
/usr/lib/x86_64-linux-gnu/libboost_date_time.so.1.74.0 \
|
||||
/usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.74.0 \
|
||||
/usr/lib/x86_64-linux-gnu/libboost_regex.so.1.74.0 \
|
||||
/usr/lib/x86_64-linux-gnu/libboost_serialization.so.1.74.0 \
|
||||
/usr/lib/x86_64-linux-gnu/libboost_thread.so.1.74.0 \
|
||||
/usr/lib/x86_64-linux-gnu/libboost_system.so.1.74.0 \
|
||||
/usr/lib/x86_64-linux-gnu/libboost_chrono.so.1.74.0 \
|
||||
/usr/lib/x86_64-linux-gnu/libboost_program_options.so.1.74.0 \
|
||||
/usr/lib/x86_64-linux-gnu/
|
||||
|
||||
RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \
|
||||
ldconfig
|
||||
|
||||
# Copy the relevant configuration files for gNB
|
||||
WORKDIR /opt/oai-gnb/etc
|
||||
COPY --from=gnb-build /oai-ran/docker/etc .
|
||||
|
||||
# Copy relevant netopeer/sysrepo files for gNB
|
||||
COPY --from=gnb-build \
|
||||
/usr/local/bin/yanglint \
|
||||
/usr/local/bin/yangre \
|
||||
/usr/local/bin/sysrepo-plugind \
|
||||
/usr/local/bin/sysrepocfg \
|
||||
/usr/local/bin/sysrepoctl \
|
||||
/usr/local/bin/netopeer2-cli \
|
||||
/usr/local/bin/
|
||||
|
||||
COPY --from=gnb-build /usr/local/sbin/netopeer2-server /usr/local/sbin/netopeer2-server
|
||||
COPY --from=gnb-build \
|
||||
/usr/local/lib/libcurl.so \
|
||||
/usr/local/lib/libnetconf2.so \
|
||||
/usr/local/lib/libssh.so \
|
||||
/usr/local/lib/libsysrepo.so \
|
||||
/usr/local/lib/libyang.so \
|
||||
/usr/local/lib/sysrepo-plugind/ \
|
||||
/usr/local/lib/
|
||||
|
||||
RUN ldconfig
|
||||
|
||||
COPY --from=gnb-build /usr/local/share/yang /usr/local/share/yang
|
||||
COPY --from=gnb-build /usr/local/share/netopeer2 /usr/local/share/netopeer2
|
||||
COPY --from=gnb-build /etc/sysrepo /etc/sysrepo
|
||||
|
||||
|
||||
# Add netconf user and configure access
|
||||
RUN \
|
||||
adduser netconf && \
|
||||
echo "netconf:netconf!" | chpasswd && \
|
||||
mkdir -p /home/netconf/.ssh
|
||||
|
||||
### FTP and SFTP configuration
|
||||
RUN \
|
||||
mkdir /ftp && \
|
||||
chown -R netconf:netconf /ftp && \
|
||||
mkdir /var/run/vsftpd && \
|
||||
mkdir /var/run/vsftpd/empty && \
|
||||
mkdir /run/sshd && \
|
||||
echo "Match User netconf\n ChrootDirectory /\n X11Forwarding no\n AllowTcpForwarding no\n ForceCommand internal-sftp -d /ftp" >> /etc/ssh/sshd_config
|
||||
|
||||
COPY docker/config/vsftpd.conf /etc/vsftpd.conf
|
||||
COPY docker/config/vsftpd.userlist /etc/vsftpd.userlist
|
||||
|
||||
|
||||
# # Initialize netopeer2
|
||||
RUN \
|
||||
/usr/local/share/netopeer2/merge_hostkey.sh && \
|
||||
/usr/local/share/netopeer2/merge_config.sh
|
||||
|
||||
COPY docker/scripts/gnb_entrypoint.sh /opt/oai-gnb/bin/entrypoint.sh
|
||||
|
||||
WORKDIR /opt/oai-gnb
|
||||
#EXPOSE 2152/udp # S1U, GTP/UDP
|
||||
#EXPOSE 22100/tcp # ?
|
||||
#EXPOSE 36412/udp # S1C, SCTP/UDP
|
||||
#EXPOSE 36422/udp # X2C, SCTP/UDP
|
||||
#EXPOSE 50000/udp # IF5 / ORI (control)
|
||||
#EXPOSE 50001/udp # IF5 / ECPRI (data)
|
||||
|
||||
ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"]
|
||||
CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"]
|
||||
@@ -116,6 +116,7 @@ For example, the eNB:
|
||||
|
||||
```bash
|
||||
docker build --target oai-enb --tag oai-enb:latest --file docker/Dockerfile.eNB.ubuntu18 .
|
||||
docker build --target oai-gnb --tag oai-gnb:latest --file docker/Dockerfile.gNB.ubuntu22 .
|
||||
```
|
||||
|
||||
After a while:
|
||||
|
||||
36
docker/config/vsftpd.conf
Normal file
36
docker/config/vsftpd.conf
Normal file
@@ -0,0 +1,36 @@
|
||||
listen=NO
|
||||
listen_ipv6=YES
|
||||
anonymous_enable=NO
|
||||
local_enable=YES
|
||||
write_enable=YES
|
||||
local_umask=022
|
||||
dirmessage_enable=YES
|
||||
use_localtime=YES
|
||||
xferlog_enable=YES
|
||||
connect_from_port_20=YES
|
||||
chroot_local_user=YES
|
||||
secure_chroot_dir=/var/run/vsftpd/empty
|
||||
pam_service_name=vsftpd
|
||||
pasv_enable=Yes
|
||||
pasv_min_port=10000
|
||||
pasv_max_port=11000
|
||||
user_sub_token=$USER
|
||||
local_root=/ftp
|
||||
userlist_enable=YES
|
||||
userlist_file=/etc/vsftpd.userlist
|
||||
userlist_deny=NO
|
||||
pasv_promiscuous=YES
|
||||
|
||||
allow_writeable_chroot=YES
|
||||
|
||||
# rsa_cert_file=/home/netconf/.ssh/melacon.server.crt
|
||||
# rsa_private_key_file=/home/netconf/.ssh/melacon.server.key
|
||||
# ssl_enable=YES
|
||||
# allow_anon_ssl=NO
|
||||
# force_local_data_ssl=YES
|
||||
# force_local_logins_ssl=YES
|
||||
# ssl_tlsv1=YES
|
||||
# ssl_sslv2=NO
|
||||
# ssl_sslv3=NO
|
||||
# require_ssl_reuse=NO
|
||||
# ssl_ciphers=HIGH
|
||||
1
docker/config/vsftpd.userlist
Normal file
1
docker/config/vsftpd.userlist
Normal file
@@ -0,0 +1 @@
|
||||
netconf
|
||||
@@ -21,6 +21,7 @@ if [[ -v USE_VOLUMED_CONF ]]; then cp $PREFIX/etc/mounted.conf $PREFIX/etc/gnb.c
|
||||
# Defualt Parameters
|
||||
GNB_ID=${GNB_ID:-e00}
|
||||
NSSAI_SD=${NSSAI_SD:-ffffff}
|
||||
ENABLE_NETCONF=${ENABLE_NETCONF:-"false"}
|
||||
# AMF_IP_ADDRESS can be amf ip address of amf fqdn
|
||||
if [[ -v AMF_IP_ADDRESS ]] && [[ "${AMF_IP_ADDRESS}" =~ [a-zA-Z] ]] && [[ -z `getent hosts $AMF_IP_ADDRESS | awk '{print $1}'` ]]; then echo "not able to resolve AMF FQDN" && exit 1 ; fi
|
||||
[[ -v AMF_IP_ADDRESS ]] && [[ "${AMF_IP_ADDRESS}" =~ [a-zA-Z] ]] && AMF_IP_ADDRESS=$(getent hosts $AMF_IP_ADDRESS | awk '{print $1}')
|
||||
@@ -72,7 +73,19 @@ elif [[ -v USE_N3XX ]]; then
|
||||
fi
|
||||
|
||||
# enable printing of stack traces on assert
|
||||
export gdbStacks=1
|
||||
export gdbStacks=0
|
||||
if $ENABLE_NETCONF; then
|
||||
echo "clearing shared memory for sysrepo"
|
||||
rm -rf /dev/shm/sr*
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "succeeded"
|
||||
else
|
||||
echo "failed"
|
||||
fi
|
||||
echo "=================================="
|
||||
echo "== starting netconf server in background"
|
||||
netopeer2-server -v2 -d &
|
||||
fi
|
||||
|
||||
echo "=================================="
|
||||
echo "== Starting gNB soft modem"
|
||||
@@ -92,3 +105,4 @@ else
|
||||
echo "$@"
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
|
||||
78
docker/scripts/netconf_dep_install.sh
Executable file
78
docker/scripts/netconf_dep_install.sh
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/bin/bash
|
||||
|
||||
INSTALL_PATH="/opt/dev/install"
|
||||
|
||||
# exit when any command fails
|
||||
set -e
|
||||
|
||||
BUILD_MODE="Release"
|
||||
|
||||
# supress warnings from git
|
||||
git config --global advice.detachedHead false
|
||||
|
||||
mkdir -p $INSTALL_PATH
|
||||
|
||||
# build and install libssh-dev
|
||||
cd $INSTALL_PATH
|
||||
git clone --single-branch --branch libssh-0.9.2 https://git.libssh.org/projects/libssh.git
|
||||
cd $INSTALL_PATH/libssh
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DWITH_EXAMPLES=OFF ..
|
||||
make -j4
|
||||
make install
|
||||
ldconfig
|
||||
|
||||
# build and install libyang
|
||||
cd $INSTALL_PATH
|
||||
git clone --single-branch --branch v2.1.30 https://github.com/CESNET/libyang.git
|
||||
cd $INSTALL_PATH/libyang
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE:String="$BUILD_MODE" -DGEN_LANGUAGE_BINDINGS=ON -DENABLE_BUILD_TESTS=OFF ..
|
||||
make -j4
|
||||
make install
|
||||
ldconfig
|
||||
|
||||
# build and install sysrepo
|
||||
cd $INSTALL_PATH
|
||||
git clone --single-branch --branch v2.2.36 https://github.com/sysrepo/sysrepo.git
|
||||
cd $INSTALL_PATH/sysrepo
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE:String="$BUILD_MODE" -DGEN_LANGUAGE_BINDINGS=ON -DGEN_CPP_BINDINGS=ON -DGEN_PYTHON_BINDINGS=OFF -DENABLE_TESTS=OFF -DREPOSITORY_LOC:PATH=/etc/sysrepo -DREQUEST_TIMEOUT=60 -DOPER_DATA_PROVIDE_TIMEOUT=60 ..
|
||||
make -j4
|
||||
make install
|
||||
ldconfig
|
||||
|
||||
# build and install libnetconf2
|
||||
cd $INSTALL_PATH
|
||||
git clone --single-branch --branch v2.1.28 https://github.com/CESNET/libnetconf2.git
|
||||
cd $INSTALL_PATH/libnetconf2
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE:String="$BUILD_MODE" -DENABLE_BUILD_TESTS=OFF ..
|
||||
make -j4
|
||||
make install
|
||||
ldconfig
|
||||
|
||||
# build and install netopeer2
|
||||
cd $INSTALL_PATH
|
||||
git clone --single-branch --branch v2.1.49 https://github.com/CESNET/netopeer2.git
|
||||
cd $INSTALL_PATH/netopeer2
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE:String="$BUILD_MODE" -DGENERATE_HOSTKEY=OFF -DMERGE_LISTEN_CONFIG=OFF ..
|
||||
make -j4
|
||||
make install
|
||||
|
||||
# build and install cURL
|
||||
cd $INSTALL_PATH
|
||||
git clone --single-branch --branch curl-7_87_0 https://github.com/curl/curl.git
|
||||
cd $INSTALL_PATH/curl
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DBUILD_TESTING=OFF ..
|
||||
make -j4
|
||||
make install
|
||||
ldconfig
|
||||
@@ -55,8 +55,6 @@
|
||||
#include <openair1/PHY/phy_extern_ue.h>
|
||||
|
||||
#include "PHY/phy_vars.h"
|
||||
#include "SCHED/sched_common_vars.h"
|
||||
#include "LAYER2/MAC/mac_vars.h"
|
||||
|
||||
#include "LAYER2/MAC/mac.h"
|
||||
#include "LAYER2/MAC/mac_proto.h"
|
||||
@@ -107,6 +105,7 @@ uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75,
|
||||
|
||||
|
||||
int oai_exit = 0;
|
||||
int NB_UE_INST = 0;
|
||||
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
@@ -88,9 +88,9 @@
|
||||
/* command line parameters specific to UE */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
// clang-format off
|
||||
#define CMDLINE_UEPARAMS_DESC { \
|
||||
{"U", CONFIG_HLP_NUMUE, 0, u16ptr:&NB_UE_INST, defuintval:1, TYPE_UINT16, 0}, \
|
||||
{"U", CONFIG_HLP_NUMUE, 0, iptr:&NB_UE_INST, defuintval:1, TYPE_INT, 0}, \
|
||||
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:130, TYPE_DOUBLE, 0}, \
|
||||
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \
|
||||
{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
|
||||
@@ -100,8 +100,7 @@
|
||||
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:23, TYPE_INT, 0}, \
|
||||
{"emul-iface", CONFIG_HLP_EMULIFACE, 0, strptr:&emul_iface, defstrval:"lo", TYPE_STRING, 100}, \
|
||||
{"L2-emul", NULL, 0, u8ptr:&nfapi_mode, defuintval:3, TYPE_UINT8, 0}, \
|
||||
{"num-ues", NULL, 0, u16ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT16, 0}, \
|
||||
{"nums_ue_thread", NULL, 0, u16ptr:&(NB_THREAD_INST), defuintval:1, TYPE_UINT16, 0}, \
|
||||
{"num-ues", NULL, 0, iptr:&(NB_UE_INST), defuintval:1, TYPE_INT, 0}, \
|
||||
{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \
|
||||
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
|
||||
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:&usrp_args, defstrval:"type=b200",TYPE_STRING, 0}, \
|
||||
@@ -111,6 +110,7 @@
|
||||
{"ue-idx-standalone", NULL, 0, u16ptr:&ue_idx_standalone, defuintval:0xFFFF, TYPE_UINT16, 0}, \
|
||||
{"node-number", NULL, 0, u16ptr:&node_number, defuintval:2, TYPE_UINT16, 0}, \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* command line parameters specific to UE threads */
|
||||
|
||||
@@ -69,7 +69,7 @@ extern double cpuf;
|
||||
#define FRAME_PERIOD 100000000ULL
|
||||
#define DAQ_PERIOD 66667ULL
|
||||
#define FIFO_PRIORITY 40
|
||||
|
||||
#define NB_THREAD_INST 1
|
||||
typedef enum {
|
||||
pss=0,
|
||||
pbch=1,
|
||||
|
||||
@@ -54,11 +54,8 @@
|
||||
|
||||
#include "PHY/phy_vars_ue.h"
|
||||
#include "PHY/LTE_TRANSPORT/transport_vars.h"
|
||||
#include "SCHED/sched_common_vars.h"
|
||||
#include "PHY/MODULATION/modulation_vars.h"
|
||||
|
||||
#include "LAYER2/MAC/mac.h"
|
||||
#include "LAYER2/MAC/mac_vars.h"
|
||||
#include "LAYER2/MAC/mac_proto.h"
|
||||
#include "RRC/LTE/rrc_vars.h"
|
||||
#include "PHY_INTERFACE/phy_interface_vars.h"
|
||||
@@ -102,7 +99,7 @@ uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75,
|
||||
int oai_exit = 0;
|
||||
|
||||
unsigned int mmapped_dma=0;
|
||||
|
||||
UE_MAC_INST *UE_mac_inst = NULL;
|
||||
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
@@ -518,14 +515,14 @@ AssertFatal(false,"");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int NB_UE_INST = 1;
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
|
||||
int CC_id;
|
||||
uint8_t abstraction_flag=0;
|
||||
// Default value for the number of UEs. It will hold,
|
||||
// if not changed from the command line option --num-ues
|
||||
NB_UE_INST=1;
|
||||
NB_THREAD_INST=1;
|
||||
configmodule_interface_t *config_mod;
|
||||
start_background_system();
|
||||
config_mod = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY);
|
||||
@@ -552,18 +549,6 @@ int main( int argc, char **argv ) {
|
||||
EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1;
|
||||
printf("Running with %d UE instances\n",NB_UE_INST);
|
||||
|
||||
// Checking option of nums_ue_thread.
|
||||
if(NB_THREAD_INST < 1) {
|
||||
printf("Running with 0 UE rxtx thread, exiting.\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
// Checking option's relation between nums_ue_thread and num-ues
|
||||
if(NB_UE_INST <NB_THREAD_INST ) {
|
||||
printf("Number of UEs < number of UE rxtx threads, exiting.\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
#if T_TRACER
|
||||
T_Config_Init();
|
||||
#endif
|
||||
@@ -606,8 +591,6 @@ int main( int argc, char **argv ) {
|
||||
frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later
|
||||
}
|
||||
|
||||
NB_INST=1;
|
||||
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) {
|
||||
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE **)*NB_UE_INST);
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@ static int DEFENBS[] = {0};
|
||||
#include <openair2/UTIL/OPT/opt.h>
|
||||
#include <openair1/SIMULATION/TOOLS/sim.h>
|
||||
#include <openair1/PHY/phy_vars.h>
|
||||
#include <openair1/SCHED/sched_common_vars.h>
|
||||
#include <openair2/LAYER2/MAC/mac_vars.h>
|
||||
#include <openair2/RRC/LTE/rrc_vars.h>
|
||||
|
||||
|
||||
@@ -48,9 +48,7 @@
|
||||
#include "radio/COMMON/common_lib.h"
|
||||
#include "radio/ETHERNET/USERSPACE/LIB/if_defs.h"
|
||||
|
||||
|
||||
#include "PHY/phy_vars.h"
|
||||
#include "SCHED/sched_common_vars.h"
|
||||
#include "PHY/TOOLS/phy_scope_interface.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
|
||||
@@ -622,6 +622,7 @@ void *emulatedRF_thread(void *param) {
|
||||
void rx_rf(RU_t *ru,int *frame,int *slot) {
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
openair0_config_t *cfg = &ru->openair0_cfg;
|
||||
void *rxp[ru->nb_rx];
|
||||
unsigned int rxs;
|
||||
int i;
|
||||
@@ -658,10 +659,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
|
||||
//"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_subframe,rxs);
|
||||
if (rxs != samples_per_slot) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",samples_per_slot,rxs);
|
||||
|
||||
if (proc->first_rx == 1) {
|
||||
ru->ts_offset = proc->timestamp_rx;
|
||||
proc->timestamp_rx = 0;
|
||||
} else {
|
||||
if (proc->first_rx != 1) {
|
||||
samples_per_slot_prev = fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp);
|
||||
|
||||
if (proc->timestamp_rx - old_ts != samples_per_slot_prev) {
|
||||
@@ -671,13 +669,22 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
|
||||
}
|
||||
}
|
||||
|
||||
//compute system frame number (SFN) according to O-RAN-WG4-CUS.0-v02.00 (using alpha=beta=0)
|
||||
// this assumes that the USRP has been synchronized to the GPS time
|
||||
// OAI uses timestamps in sample time stored in int64_t, but it will fit in double precision for many years to come.
|
||||
double gps_sec = ((double) ts)/cfg->sample_rate;
|
||||
//proc->frame_rx = ((int64_t) (gps_sec/0.01)) & 1023;
|
||||
|
||||
// in fact the following line is the same as long as the timestamp_rx is synchronized to GPS.
|
||||
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023;
|
||||
proc->tti_rx = fp->get_slot_from_timestamp(proc->timestamp_rx,fp);
|
||||
// synchronize first reception to frame 0 subframe 0
|
||||
LOG_D(PHY,"RU %d/%d TS %llu , frame %d, slot %d.%d / %d\n",
|
||||
LOG_D(PHY,"RU %d/%d TS %ld, GPS %f, SR %f, frame %d, slot %d.%d / %d\n",
|
||||
ru->idx,
|
||||
0,
|
||||
(unsigned long long int)(proc->timestamp_rx+ru->ts_offset),
|
||||
ts, //(unsigned long long int)(proc->timestamp_rx+ru->ts_offset),
|
||||
gps_sec,
|
||||
cfg->sample_rate,
|
||||
proc->frame_rx,proc->tti_rx,proc->tti_tx,fp->slots_per_frame);
|
||||
|
||||
// dump VCD output for first RU in list
|
||||
|
||||
@@ -45,8 +45,6 @@
|
||||
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
|
||||
|
||||
#include "PHY/phy_vars.h"
|
||||
#include "SCHED/sched_common_vars.h"
|
||||
#include "LAYER2/MAC/mac_vars.h"
|
||||
#include "RRC/LTE/rrc_vars.h"
|
||||
#include "PHY_INTERFACE/phy_interface_vars.h"
|
||||
#include "gnb_config.h"
|
||||
@@ -81,6 +79,8 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
|
||||
#include "common/utils/netconf/netconf.h"
|
||||
|
||||
pthread_cond_t nfapi_sync_cond;
|
||||
pthread_mutex_t nfapi_sync_mutex;
|
||||
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
|
||||
@@ -95,6 +95,8 @@ int config_sync_var=-1;
|
||||
volatile int start_gNB = 0;
|
||||
int oai_exit = 0;
|
||||
|
||||
int NB_UE_INST = 0;
|
||||
|
||||
static int wait_for_sync = 0;
|
||||
|
||||
unsigned int mmapped_dma=0;
|
||||
@@ -523,6 +525,10 @@ int main( int argc, char **argv ) {
|
||||
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
|
||||
}
|
||||
|
||||
//netconf
|
||||
netconf_init();
|
||||
|
||||
|
||||
set_softmodem_sighandler();
|
||||
#ifdef DEBUG_CONSOLE
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
@@ -727,6 +733,7 @@ int main( int argc, char **argv ) {
|
||||
}
|
||||
|
||||
logClean();
|
||||
netconf_free();
|
||||
printf("Bye.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -42,12 +42,9 @@
|
||||
#include "openair1/PHY/MODULATION/nr_modulation.h"
|
||||
#include "PHY/phy_vars_nr_ue.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
#include "SCHED/sched_common_vars.h"
|
||||
#include "PHY/MODULATION/modulation_vars.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
|
||||
//#include "../../SIMU/USER/init_lte.h"
|
||||
|
||||
#include "LAYER2/MAC/mac_vars.h"
|
||||
#include "RRC/LTE/rrc_vars.h"
|
||||
#include "PHY_INTERFACE/phy_interface_vars.h"
|
||||
#include "NR_IF_Module.h"
|
||||
@@ -403,6 +400,7 @@ static void get_channel_model_mode() {
|
||||
init_bler_table("NR_AWGN_RESULTS_DIR");
|
||||
}
|
||||
|
||||
int NB_UE_INST = 1;
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
int set_exe_prio = 1;
|
||||
@@ -469,8 +467,6 @@ int main( int argc, char **argv ) {
|
||||
}
|
||||
}
|
||||
|
||||
NB_UE_INST=1;
|
||||
NB_INST=1;
|
||||
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE **));
|
||||
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE *)*MAX_NUM_CCs);
|
||||
if (get_softmodem_params()->emulate_l1) {
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#include "openair1/SIMULATION/TOOLS/sim.h"
|
||||
#include "enb_config.h"
|
||||
#include "enb_paramdef.h"
|
||||
#include "platform_constants.h"
|
||||
#include "common/platform_constants.h"
|
||||
#include "common/config/config_paramdesc.h"
|
||||
#include "common/config/config_userapi.h"
|
||||
#include "common/ran_context.h"
|
||||
@@ -180,11 +180,12 @@ int ru_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SIM_DO_UL_SIGNAL,1);
|
||||
do_UL_sig(&sim,
|
||||
subframe,
|
||||
0, // abstraction_flag
|
||||
0, // abstraction_flag
|
||||
RC.ru[ru_id]->frame_parms,
|
||||
0, // frame is only used for abstraction
|
||||
0, // frame is only used for abstraction
|
||||
ru_id,
|
||||
CC_id);
|
||||
CC_id,
|
||||
1);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SIM_DO_UL_SIGNAL,0);
|
||||
}
|
||||
|
||||
|
||||
29
integration/.env
Normal file
29
integration/.env
Normal file
@@ -0,0 +1,29 @@
|
||||
ADMIN_PASSWORD=admin
|
||||
PUBPORT_SDNCWEB=8080
|
||||
PUBPORT_VES=8443
|
||||
SDNC_WEB_IMAGE=nexus3.onap.org:10001/onap/sdnc-web-image:2.4.2
|
||||
#SDNC_IMAGE=nexus3.onap.org:10001/onap/sdnc-image:2.4.2
|
||||
SDNC_IMAGE=hightec/sdnc-image:1.4.0-SNAPSHOT-20230213T025757Z
|
||||
SDNRDB_IMAGE=docker.elastic.co/elasticsearch/elasticsearch-oss:7.9.3
|
||||
VES_COLLECTOR_IMAGE=nexus3.onap.org:10001/onap/org.onap.dcaegen2.collectors.ves.vescollector:1.8.0
|
||||
ZOOKEEPER_IMAGE=nexus3.onap.org:10001/onap/dmaap/zookeeper:6.0.3
|
||||
KAFKA_IMAGE=nexus3.onap.org:10001/onap/dmaap/kafka111:1.0.4
|
||||
DMAAP_IMAGE=nexus3.onap.org:10001/onap/dmaap/dmaap-mr:1.1.18
|
||||
DMAAP_DR_DB_IMAGE=nexus3.onap.org:10001/mariadb:10.2.14
|
||||
# dcae configs
|
||||
PM_MAPPER_TARGET_CONFIG_PATH=/app-config/application_config.yaml
|
||||
SOLUTION_DOMAIN=local
|
||||
DCAE_VES_COLLECTOR_IMAGE=nexus3.onap.org:10001/onap/org.onap.dcaegen2.collectors.ves.vescollector:1.10.3
|
||||
|
||||
PM_MAPPER_IMAGE=nexus3.onap.org:10001/onap/org.onap.dcaegen2.services.pm-mapper:latest
|
||||
PM_MAPPER_TARGET_CONFIG_PATH=/app-config/application_config.yaml
|
||||
## oh oh
|
||||
DCAE_DFC_IMAGE=nexus3.onap.org:10003/onap/org.onap.dcaegen2.collectors.datafile.datafile-app-server:latest
|
||||
DCAE_DFC_TARGET_CONFIG_PATH=/app-config/application_config.yaml
|
||||
DCAE_DFC_TARGET_SPRING_CONFIG=/opt/app/datafile/config/application.yaml
|
||||
#dmaap config
|
||||
DMAAP_DR_NODE_IMAGE=nexus3.onap.org:10001/onap/dmaap/datarouter-node:2.1.11
|
||||
DMAAP_DR_PROV_IP_IMAGE=nexus3.onap.org:10001/onap/dmaap/datarouter-prov:2.1.11
|
||||
DMAAP_KAFKA_IMAGE=nexus3.onap.org:10001/onap/dmaap/kafka111:1.0.4
|
||||
DMAAP_MR_IMAGE=nexus3.onap.org:10001/onap/dmaap/dmaap-mr:1.1.18
|
||||
DMAAP_ZOOKEEPER_IMAGE=nexus3.onap.org:10001/onap/dmaap/zookeeper:6.0.3
|
||||
120
integration/README.md
Normal file
120
integration/README.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Integration
|
||||
|
||||
## How to build gNodeB image
|
||||
|
||||
We created a script which is doing the same as the instructions inside of the docker folder.
|
||||
```
|
||||
./build-gnb-docker.sh --base --build --gnb
|
||||
```
|
||||
|
||||
If the base is already created once, only ```--build``` and ```--gnb``` args are neccessary.
|
||||
|
||||
|
||||
## How to run
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* docker (sudo apt install docker.io)
|
||||
* docker-compose (pip3 install docker-compose)
|
||||
|
||||
|
||||
### Start SDN-Controller and its components
|
||||
|
||||
* edit ```.env``` file to set image versions and public available ports
|
||||
* run cmd:
|
||||
```
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
|
||||
### Start gNodeB
|
||||
|
||||
|
||||
```
|
||||
docker-compose -f docker-compose.gnb.yml up -d
|
||||
```
|
||||
|
||||
depending on if VES is configured or not you have to mount the device manually.
|
||||
|
||||
### Go to ODLUX gui
|
||||
|
||||
* Open URL in the browser: http://your-deployed-ip-address:8181
|
||||
* login with credentials defined in .env file (default: admin:admin)
|
||||
* find out ip address of the gnodeb container (```docker inspect gnodeb01-test | grep -i ipaddress)
|
||||
* mount the device in the connectApp
|
||||
* node-id: whatever you like
|
||||
* host: ip address you found out
|
||||
* port: 830
|
||||
* username: netconf
|
||||
* password: netconf!
|
||||
* now the node should get into the connected state
|
||||
|
||||
|
||||
## Using ODLUX Gui
|
||||
|
||||
By default this is available on ```http://localhost:8080```. Default user credentials are username ```admin``` and password ```admin```. The password is configured in the .env file ```ADMIN_PASSWORD```.
|
||||
|
||||
On an already started OAI gNodeB you should already see the an entry in the ConnectApp in state ```Connected```. The node-id is corresponding with the gnb.conf of the device. By right-click on it you can see in the context menu ```Info``` all the supported yang specifications, this device is supporting.
|
||||
|
||||
If the gnb.conf property ```demoAlarmingInterval``` is set, you should also see an alarm inside of the FaultApp. There you have also a tab ```Alarm Log``` which shows the complete history of incoming alarms into the SDNC.
|
||||
|
||||
HINT: If you want to see Notifications as they are coming into the SDNC you have to enable Notifications. Therefore you have to click on your username on the top right corner and then go to settings. There you can enable and disable it. It is disabled by default to prevent flooding the browser with incoming messages, which can cause some instability.
|
||||
|
||||
In the ConfigurationApp you are able to read and write configuration from and to the device. Sadly up to now there is a bug in the opendaylight project which is preventing to access a List of objects in the root structure, which is the way 3GPP has designed their Models. Since we are just implementing one root element this list has now the size of one, we have to access this by url and cannot click through from beginning.
|
||||
```
|
||||
http://localhost:8080/odlux/index.html#/configuration/{node-id}/_3gpp-common-managed-element:ManagedElement[OAI%20gNodeB]
|
||||
|
||||
```
|
||||
|
||||
But from there on you have access to all the containers and leafs inside.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Node does not get into connected state
|
||||
|
||||
* check if the gnodeb container is running
|
||||
* get inside of the gnodeb container and check if the netopeer2 server is running
|
||||
|
||||
```
|
||||
docker exec -ti gnodeb-test bash
|
||||
ps -ef | grep netopeer
|
||||
```
|
||||
* check if exceptions are thrown inside of the SDN-Controller
|
||||
```
|
||||
docker exec -ti sdnc bash
|
||||
less /opt/opendaylight/data/log/karaf.log
|
||||
go to the end of the log (SHIFT+G) and then upwards to search for exceptions/stacktraces (e.g. wrong username or password)
|
||||
```
|
||||
|
||||
### Node does not even show up after started up
|
||||
|
||||
* check the gnb.conf if ```vesUrl``` is correct
|
||||
* check the VES-Collector if message is coming in
|
||||
|
||||
```
|
||||
$ docker logs -f dcae-ves-collector
|
||||
```
|
||||
* there should be a log with something like
|
||||
```
|
||||
2023-03-20 13:12:59.697 INFO 28 [nio-8443-exec-5] o.o.d.c.p.MessageRouterHttpStatusMapper : Successfully send event to MR
|
||||
```
|
||||
* if not please check the gnb logs
|
||||
* if yes please make sure that all components of the docker-compose.yml are up running
|
||||
```
|
||||
$ docker-compose ps -a
|
||||
Name Command State Ports
|
||||
-------------------------------------------------------------------------------------------------------------------------
|
||||
dcae-dfc java -jar /opt/app/datafil ... Up 8100/tcp, 8433/tcp
|
||||
dcae-pm-mapper java -jar pm-mapper-1.10.0.jar Up
|
||||
dcae-ves-collector /bin/sh -c bin/docker-entry.sh Up 8080/tcp, 8443/tcp
|
||||
dmaap-dr-mariadb docker-entrypoint.sh mysqld Up (healthy) 3306/tcp
|
||||
dmaap-dr-node sh startup.sh Up 8080/tcp, 8443/tcp
|
||||
dmaap-dr-prov sh startup.sh Up (healthy) 8080/tcp, 8443/tcp
|
||||
dmaap-kafka /etc/confluent/docker/run Up 9092/tcp, 9093/tcp
|
||||
dmaap-message-router sh startup.sh Up 3904/tcp, 3905/tcp
|
||||
dmaap-zookeeper /etc/confluent/docker/run Up 2181/tcp, 2888/tcp, 3888/tcp
|
||||
sdnc /bin/sh -c /opt/onap/sdnc/ ... Up 1090/tcp, 1099/tcp, 8181/tcp
|
||||
sdnc-web /opt/bitnami/scripts/nginx ... Up 0.0.0.0:8080->8080/tcp,:::8080->8080/tcp, 8443/tcp
|
||||
sdnrdb /tini -- /usr/local/bin/do ... Up 9200/tcp, 9300/tcp
|
||||
```
|
||||
|
||||
BIN
integration/dcae/certs/cert.jks
Normal file
BIN
integration/dcae/certs/cert.jks
Normal file
Binary file not shown.
1
integration/dcae/certs/jks.pass
Normal file
1
integration/dcae/certs/jks.pass
Normal file
@@ -0,0 +1 @@
|
||||
Er1tmip;T4w[%1}YE?x{fN9v
|
||||
BIN
integration/dcae/certs/trust.jks
Normal file
BIN
integration/dcae/certs/trust.jks
Normal file
Binary file not shown.
1
integration/dcae/certs/trust.pass
Normal file
1
integration/dcae/certs/trust.pass
Normal file
@@ -0,0 +1 @@
|
||||
583Ls;XF(qDQu3p!L22gyh1t
|
||||
76
integration/dcae/collector.properties
Normal file
76
integration/dcae/collector.properties
Normal file
@@ -0,0 +1,76 @@
|
||||
###############################################################################
|
||||
##
|
||||
## Collector Server config
|
||||
##
|
||||
## - Default values are shown as commented settings.
|
||||
##
|
||||
###############################################################################
|
||||
##
|
||||
## HTTP(S) service
|
||||
##
|
||||
## Normally:
|
||||
##
|
||||
## - 8080 is http service
|
||||
## - https is disabled by default
|
||||
##
|
||||
## - At this time, the server always binds to 0.0.0.0
|
||||
##
|
||||
##
|
||||
#collector.service.port=8080
|
||||
|
||||
## Authentication is only supported via secure port
|
||||
## When enabled - require valid keystore defined
|
||||
collector.service.secure.port=8443
|
||||
|
||||
# auth.method flags:
|
||||
#
|
||||
# noAuth - default option - no security (http)
|
||||
# certBasicAuth - auth by certificate and basic auth username / password (https)
|
||||
auth.method=certBasicAuth
|
||||
|
||||
## Combination of userid,hashPassword encoded pwd list to be supported
|
||||
## userid and pwd comma separated; pipe delimitation between each pair
|
||||
## Password is generated by crypt-password library using BCrypt algorithm stored in dcaegen2/sdk package
|
||||
## or https://nexus.onap.org/#nexus-search;quick~crypt-password
|
||||
header.authlist=sample1,$2a$10$0buh.2WeYwN868YMwnNNEuNEAMNYVU9.FSMJGyIKV3dGET/7oGOi6
|
||||
|
||||
## The keystore must be setup per installation when secure port is configured
|
||||
collector.keystore.file.location=etc/keystore
|
||||
collector.keystore.passwordfile=etc/passwordfile
|
||||
|
||||
collector.cert.subject.matcher=etc/certSubjectMatcher.properties
|
||||
|
||||
## The truststore must be setup per installation when mutual tls support is configured
|
||||
collector.truststore.file.location=etc/truststore
|
||||
collector.truststore.passwordfile=etc/trustpasswordfile
|
||||
|
||||
## Schema Validation checkflag
|
||||
## default no validation checkflag (-1)
|
||||
## If enabled (1) - schemafile location must be specified
|
||||
collector.schema.checkflag=1
|
||||
collector.schema.file={\"v1\":\"./etc/CommonEventFormat_27.2.json\",\"v2\":\"./etc/CommonEventFormat_27.2.json\",\"v3\":\"./etc/CommonEventFormat_27.2.json\",\"v4\":\"./etc/CommonEventFormat_27.2.json\",\"v5\":\"./etc/CommonEventFormat_28.4.1.json\",\"v7\":\"./etc/CommonEventFormat_30.2.1_ONAP.json\"}
|
||||
|
||||
## Schema StndDefinedFields Validation checkflag
|
||||
## default no validation checkflag (-1)
|
||||
## If enabled (1) - schema files locations must be specified, mapping file path must be specified, schema reference path
|
||||
## in event json must be specified, path to stndDefined data field in event json must be specified
|
||||
collector.externalSchema.checkflag=1
|
||||
collector.externalSchema.schemasLocation=etc/externalRepo/
|
||||
collector.externalSchema.mappingFileLocation=etc/externalRepo/schema-map.json
|
||||
event.externalSchema.schemaRefPath=$.event.stndDefinedFields.schemaReference
|
||||
event.externalSchema.stndDefinedDataPath=$.event.stndDefinedFields.data
|
||||
|
||||
## List all streamid per domain to be supported. The streamid should match to channel name on dmaapfile
|
||||
collector.dmaap.streamid=fault=ves-fault|syslog=ves-syslog|heartbeat=ves-heartbeat|measurementsForVfScaling=ves-measurement|mobileFlow=ves-mobileflow|other=ves-other|stateChange=ves-statechange|thresholdCrossingAlert=ves-thresholdCrossingAlert|voiceQuality=ves-voicequality|sipSignaling=ves-sipsignaling|notification=ves-notification|pnfRegistration=ves-pnfRegistration|3GPP-FaultSupervision=ves-3gpp-fault-supervision|3GPP-Heartbeat=ves-3gpp-heartbeat|3GPP-Provisioning=ves-3gpp-provisioning|3GPP-PerformanceAssurance=ves-3gpp-performance-assurance|o-ran-sc-du-hello-world-pm-streaming-oas3=ves-o-ran-sc-du-hello-world-pm-streaming-oas3|o1-notify-pnf-registration=ves-o1-notify-pnf-registration
|
||||
collector.dmaapfile=etc/ves-dmaap-config.json
|
||||
|
||||
## Path to the file containing description of api versions
|
||||
collector.description.api.version.location=etc/api_version_description.json
|
||||
|
||||
## Event transformation Flag - when set expects configurable transformation
|
||||
## defined under ./etc/eventTransform.json
|
||||
## Enabled by default; to disable set to 0
|
||||
event.transform.flag=0
|
||||
|
||||
# Describes at what frequency (measured in minutes) should application try to fetch config from CBS
|
||||
collector.dynamic.config.update.frequency=5
|
||||
29
integration/dcae/dfc_mount_config.yaml
Normal file
29
integration/dcae/dfc_mount_config.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
dmaap.certificateConfig.keyCert: /opt/app/datafile/etc/cert/cert.p12
|
||||
dmaap.certificateConfig.keyPasswordPath: /opt/app/datafile/etc/cert/p12.pass
|
||||
dmaap.certificateConfig.trustedCa: /opt/app/datafile/etc/cert/trust.jks
|
||||
dmaap.certificateConfig.trustedCaPasswordPath: /opt/app/datafile/etc/cert/trust.pass
|
||||
dmaap.dmaapConsumerConfiguration.consumerGroup: OpenDcae-c12
|
||||
dmaap.dmaapConsumerConfiguration.consumerId: C12
|
||||
dmaap.dmaapConsumerConfiguration.timeoutMs: -1
|
||||
dmaap.security.enableDmaapCertAuth: false
|
||||
dmaap.security.keyStorePasswordPath: /opt/app/datafile/etc/cert/jks.pass
|
||||
dmaap.security.keyStorePath: /opt/app/datafile/etc/cert/cert.jks
|
||||
dmaap.security.trustStorePasswordPath: /opt/app/datafile/etc/cert/trust.pass
|
||||
dmaap.security.trustStorePath: /opt/app/datafile/etc/cert/trust.jks
|
||||
service_calls: []
|
||||
sftp.security.strictHostKeyChecking: true
|
||||
streams_publishes:
|
||||
PM_MEAS_FILES:
|
||||
dmaap_info:
|
||||
location: loc00
|
||||
log_url: https://dmaap-dr-prov:8443/feedlog/1
|
||||
password: pmmapper
|
||||
publish_url: http://dmaap-dr-prov:8080/publish/1
|
||||
publisher_id: 1.85gkg
|
||||
username: pmmapper
|
||||
type: data_router
|
||||
streams_subscribes:
|
||||
dmaap_subscriber:
|
||||
dmaap_info:
|
||||
topic_url: http://dmaap-message-router:3904/events/unauthenticated.VES_NOTIFICATION_OUTPUT
|
||||
type: message_router
|
||||
31
integration/dcae/dfc_spring_application.yaml
Normal file
31
integration/dcae/dfc_spring_application.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: prod
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: "loggers,logfile,health,info,metrics"
|
||||
server:
|
||||
port: 8433
|
||||
ssl:
|
||||
key-store-type: PKCS12
|
||||
key-store-password: ericssondfc
|
||||
key-store: classpath:keystore.jks
|
||||
key-password: ericssondfc
|
||||
keyAlias: tomcat-localhost
|
||||
logging:
|
||||
level:
|
||||
ROOT: INFO
|
||||
org.springframework: INFO
|
||||
org.springframework.data: INFO
|
||||
org.springframework.web.reactive.function.client.ExchangeFunctions: INFO
|
||||
org.onap.dcaegen2.collectors.datafile: TRACE
|
||||
org.onap.dcaegen2: TRACE
|
||||
file: /var/log/ONAP/application.log
|
||||
app:
|
||||
filepath: config/datafile_endpoints_test.json
|
||||
|
||||
springdoc:
|
||||
show-actuator: true
|
||||
swagger-ui.disable-swagger-default-url: true
|
||||
36
integration/dcae/pm_mount_config.yaml
Normal file
36
integration/dcae/pm_mount_config.yaml
Normal file
@@ -0,0 +1,36 @@
|
||||
pm-mapper-filter:
|
||||
# filters:
|
||||
# - pmDefVsn: "1.0"
|
||||
# nfType: "gnb"
|
||||
# vendor: "Nokia"
|
||||
# measTypes:
|
||||
# - attTCHSeizures
|
||||
# - succTCHSeizures2
|
||||
# - succImmediateAssignProcs8
|
||||
filters: [] #disabling filters
|
||||
key_store_path: "/opt/app/pm-mapper/etc/certs/cert.jks"
|
||||
key_store_pass_path: "/opt/app/pm-mapper/etc/certs/jks.pass"
|
||||
trust_store_path: "/opt/app/pm-mapper/etc/certs/trust.jks"
|
||||
trust_store_pass_path: "/opt/app/pm-mapper/etc/certs/trust.pass"
|
||||
dmaap_dr_delete_endpoint: "http://dmaap-dr-node:8080/delete"
|
||||
dmaap_dr_feed_name: "1"
|
||||
aaf_identity: "aaf_admin@people.osaaf.org"
|
||||
aaf_password: "demo123456!"
|
||||
enable_http: true
|
||||
streams_publishes:
|
||||
dmaap_publisher:
|
||||
type: "message_router"
|
||||
dmaap_info:
|
||||
topic_url: "http://message-router:3904/events/unauthenticated.PERFORMANCE_MEASUREMENTS"
|
||||
client_role: "org.onap.dcae.pmPublisher"
|
||||
location: "csit-pmmapper"
|
||||
client_id: "1562763644939"
|
||||
streams_subscribes:
|
||||
dmaap_subscriber:
|
||||
type: "data_router"
|
||||
dmaap_info:
|
||||
username: "username"
|
||||
password: "password"
|
||||
location: "csit-pmmapper"
|
||||
delivery_url: "http://dcae-pm-mapper:8081/delivery"
|
||||
subscriber_id: 1
|
||||
9
integration/dcae/ves-collector.externalrepo.config.json
Normal file
9
integration/dcae/ves-collector.externalrepo.config.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"destination":"/opt/app/VESCollector/etc/externalRepo",
|
||||
"repositories":[
|
||||
{
|
||||
"url":"https://forge.3gpp.org/rep/sa5/MnS.git",
|
||||
"branch":"Rel-18"
|
||||
}
|
||||
]
|
||||
}
|
||||
226
integration/dcae/ves-dmaap-config.json
Normal file
226
integration/dcae/ves-dmaap-config.json
Normal file
@@ -0,0 +1,226 @@
|
||||
{
|
||||
"ves-syslog": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-statechange": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-thresholdCrossingAlert": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-heartbeat": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.SEC_HEARTBEAT_OUTPUT/"
|
||||
}
|
||||
},
|
||||
"ves-other": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.SEC_OTHER_OUTPUT/"
|
||||
}
|
||||
},
|
||||
"ves-mobileflow": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-sipsignaling": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-voicequality": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-fault": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.SEC_FAULT_OUTPUT/"
|
||||
}
|
||||
},
|
||||
"ves-measurement": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.VES_MEASUREMENT_OUTPUT/"
|
||||
}
|
||||
},
|
||||
"ves-3gpp-fault-supervision": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.SEC_3GPP_FAULTSUPERVISION_OUTPUT/"
|
||||
}
|
||||
},
|
||||
"ves-3gpp-provisioning": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.SEC_3GPP_PROVISIONING_OUTPUT/"
|
||||
}
|
||||
},
|
||||
"ves-3gpp-heartbeat": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.SEC_3GPP_HEARTBEAT_OUTPUT/"
|
||||
}
|
||||
},
|
||||
"ves-3gpp-performance-assurance": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.SEC_3GPP_PERFORMANCEASSURANCE_OUTPUT/"
|
||||
}
|
||||
},
|
||||
"ves-syslog-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-statechange-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-thresholdCrossingAlert-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-heartbeat-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-other-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-mobileflow-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-sipsignaling-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTSves7_valid_ip_v4.json-DEV"
|
||||
}
|
||||
},
|
||||
"ves-voicequality-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-fault-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-measurement-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-3gpp-fault-supervision-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.SEC_3GPP_FAULTSUPERVISION_OUTPUT"
|
||||
}
|
||||
},
|
||||
"ves-3gpp-provisioning-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.SEC_3GPP_FAULTSUPERVISION_OUTPUT"
|
||||
}
|
||||
},
|
||||
"ves-3gpp-heartbeat-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-3gpp-performance-assurance-secondary": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/DCAE-SE-COLLECTOR-EVENTS-DEV"
|
||||
}
|
||||
},
|
||||
"ves-pnfRegistration": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.VES_PNFREG_OUTPUT/"
|
||||
}
|
||||
},
|
||||
"ves-o1-notify-pnf-registration": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.VES_O1_NOTIFY_PNF_REGISTRATION_OUTPUT/"
|
||||
}
|
||||
},
|
||||
"ves-o-ran-sc-du-hello-world-pm-streaming-oas3": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.VES_O_RAN_SC_HELLO_WORLD_PM_STREAMING_OUTPUT/"
|
||||
}
|
||||
},
|
||||
"ves-file-ready": {
|
||||
"type": "message_router",
|
||||
"dmaap_info": {
|
||||
"location": "mtl5",
|
||||
"topic_url": "http://dmaap-message-router:3904/events/unauthenticated.VES_FILE_READY_OUTPUT/"
|
||||
}
|
||||
}
|
||||
}
|
||||
16
integration/dcae/ves-image/Dockerfile
Normal file
16
integration/dcae/ves-image/Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
||||
ARG BASEIMAGE=nexus3.onap.org:10001/onap/org.onap.dcaegen2.collectors.ves.vescollector:1.8.0
|
||||
|
||||
FROM ubuntu:22.04 AS stage-0
|
||||
ARG DLREPO=https://forge.3gpp.org/rep/sa5/MnS.git
|
||||
ARG DLBRANCH=Rel-18
|
||||
RUN apt update && apt install -y python3 git
|
||||
|
||||
COPY install.py /
|
||||
|
||||
RUN python3 install.py $DLREPO $DLBRANCH /opt/app/VESCollector/etc/externalRepo
|
||||
|
||||
|
||||
FROM ${BASEIMAGE}
|
||||
|
||||
|
||||
COPY --from=stage-0 --chown=vescollector:vescollector /opt/app/VESCollector/etc/externalRepo /opt/app/VESCollector/etc/externalRepo
|
||||
133
integration/dcae/ves-image/install.py
Executable file
133
integration/dcae/ves-image/install.py
Executable file
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
import json
|
||||
import re
|
||||
from typing import List
|
||||
|
||||
class Installer:
|
||||
|
||||
def __init__(self, url, branch, dstFolder) -> None:
|
||||
self.downloadUrl = url
|
||||
self.publicUrlFormat = self.createPublicUrlFormat(url, branch)
|
||||
print(f'fmt={self.publicUrlFormat}')
|
||||
self.branch = branch
|
||||
self.baseFolder = dstFolder
|
||||
self.subfolder = self.createSubFolder(url, branch)
|
||||
|
||||
def createPublicUrlFormat(self, url:str, branch:str)->str:
|
||||
if url.endswith('.git'):
|
||||
url = url[:-4]
|
||||
if url.startswith('git@'):
|
||||
url = 'https://'+url[4:]
|
||||
fmt=url+'/raw/'+branch+'/{}'
|
||||
return fmt
|
||||
def createSubFolder(self, gitUrl:str, branch:str) -> str:
|
||||
regex = r"^[^\/]+\/\/(.*)$"
|
||||
matches = re.finditer(regex, gitUrl)
|
||||
match = next(matches)
|
||||
name = match.group(1)
|
||||
if name.endswith('.git'):
|
||||
name=name[:-4]
|
||||
tmp:List[str]=[]
|
||||
hlp1 = name.split('/')
|
||||
for h in hlp1:
|
||||
if '.' in h:
|
||||
hlp2=h.split('.')
|
||||
for h2 in hlp2:
|
||||
tmp.append(h2)
|
||||
else:
|
||||
tmp.append(h)
|
||||
|
||||
return '/'.join(tmp)+'/'+branch
|
||||
|
||||
def getDstFolder(self)->str:
|
||||
return f'{self.baseFolder}/{self.subfolder}'
|
||||
|
||||
def exec(self, cmd:str):
|
||||
output = subprocess.Popen(
|
||||
cmd, shell=True, stdout=subprocess.PIPE).stdout.read()
|
||||
return output
|
||||
|
||||
def download(self) -> bool:
|
||||
print(f'try to download repo {self.downloadUrl} to {self.getDstFolder()}')
|
||||
self.exec(f'git clone --single-branch --branch {self.branch} {self.downloadUrl} {self.getDstFolder()}')
|
||||
|
||||
def getFilesFiltered(self, lst:List[str]=None, path=None, root=None, filter=['yaml','yml'])->List[str]:
|
||||
if lst is None:
|
||||
lst=[]
|
||||
if root is None:
|
||||
root=str(self.getDstFolder())
|
||||
if path is None:
|
||||
path=self.getDstFolder()
|
||||
if os.path.exists(path) and os.path.isdir(path):
|
||||
# Iterate over all files and directories in the given path
|
||||
for filename in os.listdir(path):
|
||||
if filename.startswith("."):
|
||||
continue
|
||||
fmatch=False
|
||||
# Get the absolute path of the file/directory
|
||||
abs_path = os.path.join(path, filename)
|
||||
# If it is a directory, recursively call this function on it
|
||||
if os.path.isdir(abs_path):
|
||||
self.getFilesFiltered(lst=lst, path=abs_path, root=root, filter=filter )
|
||||
# If it is a file, print its absolute path
|
||||
elif os.path.isfile(abs_path):
|
||||
for fi in filter:
|
||||
if abs_path.endswith(fi):
|
||||
fmatch=True
|
||||
break
|
||||
if not fmatch:
|
||||
continue
|
||||
relpath=abs_path[len(root)+1:]
|
||||
lst.append(relpath)
|
||||
return lst
|
||||
|
||||
def urlAlreadyInData(self, data:List[dict], pubUrl:str, key='publicURL'):
|
||||
for item in data:
|
||||
if key in item and item[key]==pubUrl:
|
||||
return True
|
||||
return False
|
||||
|
||||
def createSchemaMap(self):
|
||||
schemaMapFile = f'{self.baseFolder}/schema-map.json'
|
||||
if os.path.isfile(schemaMapFile):
|
||||
with open(schemaMapFile) as fp:
|
||||
data = json.load(fp)
|
||||
else:
|
||||
data:List[dict] = []
|
||||
files = self.getFilesFiltered()
|
||||
for file in files:
|
||||
print(file)
|
||||
pubUrl = self.publicUrlFormat.format(file)
|
||||
if self.urlAlreadyInData(data,pubUrl):
|
||||
print(f'entry with url {pubUrl} already exists. ignoring')
|
||||
continue
|
||||
data.append({
|
||||
'publicURL': pubUrl,
|
||||
'localURL': f'{self.subfolder}/{file}'
|
||||
})
|
||||
with open(schemaMapFile,'w') as fp:
|
||||
json.dump(data,fp)
|
||||
|
||||
def printHelp():
|
||||
print("Installation script for VES additional formats")
|
||||
print(" usage: ")
|
||||
print(" install.py DOWNLOAD-REPO BRANCH DESTINATION-FOLDER")
|
||||
|
||||
args = sys.argv
|
||||
args.pop(0)
|
||||
if len(args)<3:
|
||||
print(f'bad parameters ${args}')
|
||||
printHelp()
|
||||
exit(1)
|
||||
|
||||
dlRepo = args.pop(0)
|
||||
dlBranch = args.pop(0)
|
||||
dst = args.pop(0)
|
||||
installer = Installer(dlRepo, dlBranch, dst)
|
||||
installer.download()
|
||||
|
||||
installer.createSchemaMap()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user