Skip to content
Snippets Groups Projects
Commit ec636273 authored by ismail's avatar ismail
Browse files

CI: initial ci draft

parent 13e221c7
No related branches found
No related tags found
1 merge request!7Merging tutorials
#!/bin/groovy
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
//-------------------------------------------------------------------------------
// Abstraction function to send social media messages:
// like on Slack or Mattermost
def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) {
if (params.pipelineUsesSlack != null) {
if (params.pipelineUsesSlack) {
slackSend channel: pipeChannel, color: pipeColor, message: pipeMessage
}
}
}
// Location of the CN executor node
def cn_ci_host = params.Host_CN_CI_Server
// for lock
def ds_tester_ci_resource = params.DsTester
// Location of the DsTester workspace
def dsTestFrameworkLocation = params.dsTestFrameworkLocation
// When triggered by upstream, specify which tag to use
def upstreamTagToUse = params.upstreamTagToUse
// Location of the CN tester
def dsT_host_flag = false
def dsT_host = ""
def dsT_host_user = ""
def dsT_host_ip_addr = ""
// Flags
def scmEvent = false
def upstreamEvent = false
// Default tags --> could be passed on by upstream job or by PR content
def nrfTag = params.nrfTag
def amfTag = params.amfTag
def smfTag = params.smfTag
def spgwuTag = params.spgwuTag
//-------------------------------------------------------------------------------
// Pipeline start
pipeline {
agent {
label cn_ci_host
}
options {
disableConcurrentBuilds()
timestamps()
ansiColor('xterm')
lock(cn_ci_resource)
}
stages {
stage ('Verify Parameters') {
steps {
script {
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"'
JOB_TIMESTAMP = JOB_TIMESTAMP.trim()
def allParametersPresent = true
if (params.eNB_IPAddress == null) {
allParametersPresent = false
if (params.eNB_Credentials == null) {
allParametersPresent = false
if (params.OC_Credentials == null) {
allParametersPresent = false
}
if (params.OC_ProjectName == null) {
allParametersPresent = false
}
if (allParametersPresent) {
echo "Cluster Access parameters are present"
} else {
echo "Some Cluster Access parameters are missing"
sh "./ci-scripts/fail.sh"
}
if (params.DS_Tester_Server_Flag != null) {
dsT_host_flag = params.DS_Tester_Server_Flag
if (dsT_host_flag) {
def allParametersPresent = true
if (params.DS_Tester_Server_Name == null) {
allParametersPresent = false
} else {
dsT_host = params.DS_Tester_Server_Name
}
if (params.DS_Tester_Server_Login == null) {
allParametersPresent = false
} else {
dsT_host_user = params.DS_Tester_Server_Login
}
if (params.DS_Tester_Server_IP_Addr == null) {
allParametersPresent = false
} else {
dsT_host_ip_addr = params.DS_Tester_Server_IP_Addr
}
if (allParametersPresent) {
echo "DS Tester is on ${dsT_host}"
} else {
echo "Some DS Tester parameters are missing!"
sh "./ci-scripts/fail.sh"
}
}
}
// Find out the cause of the trigger
for (cause in currentBuild.getBuildCauses()) {
if (cause.toString() ==~ /.*UpstreamCause.*/) {
upstreamEvent = true
//} else {
// scmEvent = true
}
}
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password']
]) {
if (upstreamEvent) {
if (params.NRF_TAG != null) {
nrfTag = params.NRF_TAG
echo "Upstream Job passed NRF_TAG to use: ${nrfTag}"
}
if (params.AMF_TAG != null) {
amfTag = params.AMF_TAG
echo "Upstream Job passed AMF_TAG to use: ${amfTag}"
}
if (params.SMF_TAG != null) {
smfTag = params.SMF_TAG
echo "Upstream Job passed SMF_TAG to use: ${smfTag}"
}
sh "git clean -x -d -f > /dev/null 2>&1"
sh "git fetch --prune > /dev/null 2>&1"
sh 'git checkout -f ' + upstreamTagToUse
sh "zip -r -qq oai-cn5g-fed.zip .git"
sh "mkdir -p archives DS-TEST-RESULTS"
// Prepare the workspace in the remote server
copyTo2ndServer('oai-cn5g-fed.zip', true, ${eNB_Username}, ${params.eNB_IPAddress})
myShCmd('git clean -x -d -f > /dev/null 2>&1', true, ${eNB_Username}, ${params.eNB_IPAddress})
myShCmd('mkdir -p archives DS-TEST-RESULTS', true, ${eNB_Username}, ${params.eNB_IPAddress})
}
if (scmEvent) {
sh "git clean -x -d -f > /dev/null 2>&1"
if ("MERGE".equals(env.gitlabActionType)) {
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 oai-cn5g-fed.zip .git"
sh "mkdir -p archives DS-TEST-RESULTS"
// Prepare the workspace in remote server
copyTo2ndServer('oai-cn5g-fed.zip', true, ${eNB_Username}, ${params.eNB_IPAddress})
myShCmd('git clean -x -d -f > /dev/null 2>&1', true, ${eNB_Username}, ${params.eNB_IPAddress})
if ("MERGE".equals(env.gitlabActionType)) {
myShCmd("./ci-scripts/doGitLabMerge.sh --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}", new_host_flag, new_host_user, new_host)
}
myShCmd('mkdir -p archives DS-TEST-RESULTS', true, ${eNB_Username}, ${params.eNB_IPAddress})
}
if ((!upstreamEvent) && (!scmEvent)) {
sh "git clean -x -d -f > /dev/null 2>&1"
sh "zip -r -qq oai-cn5g-fed.zip .git"
sh "mkdir -p archives DS-TEST-RESULTS"
// Prepare the workspace in the remote server
copyTo2ndServer('oai-cn5g-fed.zip', true, ${eNB_Username}, ${params.eNB_IPAddress})
myShCmd('git clean -x -d -f > /dev/null 2>&1', true, ${eNB_Username}, ${params.eNB_IPAddress})
myShCmd('mkdir -p archives DS-TEST-RESULTS', true, ${eNB_Username}, ${params.eNB_IPAddress})
}
imageTags = "oai-nrf:${nrfTag},oai-amf:${amfTag},oai-smf:${smfTag},oai-spgwu-tiny:${spgwuTag}"
}
}
}
}
stage ('Deploy Whole 5G Core Network') {
steps {
script {
echo '\u2705 \u001B[32mDeploy CN5G in idle mode\u001B[0m'
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password']
]) {
try {
sh "python3 helmDeploy.py --mode=Deploy --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName} --imageTags=${imageTags}"
} catch (Exception e) {
currentBuild.result = 'FAILURE'
}
}
}
}
}
stage ('Undeploy 5G-CN') {
steps {
script {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password']
]) {
try {
sh "python3 helmDeploy.py --mode=UnDeploy --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName} --imageTags=${imageTags}"
} catch (Exception e) {
currentBuild.result = 'FAILURE'
}
}
}
}
}
}
}
// Functions
def copyTo2ndServer(filename, flag, user, host) {
if (flag) {
if ("oai-cn5g-fed.zip".equals(filename)) {
sh "ssh ${user}@${host} 'rm -rf /tmp/CI-CN5G-FED-RHEL8'"
sh "ssh ${user}@${host} 'mkdir -p /tmp/CI-CN5G-FED-RHEL8'"
}
sh "scp ${filename} ${user}@${host}:/tmp/CI-CN5G-FED-RHEL8"
if ("oai-cn5g-fed.zip".equals(filename)) {
sh "ssh ${user}@${host} 'cd /tmp/CI-CN5G-FED-RHEL8 && unzip -qq oai-cn5g-fed.zip && rm oai-cn5g-fed.zip'"
sh "ssh ${user}@${host} 'cd /tmp/CI-CN5G-FED-RHEL8 && git checkout -f ${GIT_COMMIT}'"
sh "ssh ${user}@${host} 'cd /tmp/CI-CN5G-FED-RHEL8 && git log -n1'"
}
}
}
def copyFrom2ndServer(filename, target, flag, user, host) {
if (flag) {
sh "scp ${user}@${host}:/tmp/CI-CN5G-FED-RHEL8/${filename} ${target}"
}
}
def myShCmd(cmd, flag, user, host) {
if (flag) {
sh "ssh -t -t ${user}@${host} 'cd /tmp/CI-CN5G-FED-RHEL8 && ${cmd}'"
} else {
sh "${cmd}"
}
}
def myShCmdWithLog(cmd, logFile, flag, user, host) {
if (flag) {
sh "ssh -t -t ${user}@${host} 'export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:.:/usr/local/devsol/bin && ${cmd}' > ${logFile} 2>&1"
} else {
sh "${cmd} > ${logFile} 2>&1"
}
}
def myShRetCmd(cmd, flag, user, host) {
if (flag) {
ret = sh returnStdout: true, script: "ssh -t -t ${user}@${host} 'cd /tmp/CI-CN5G-FED-RHEL8 && ${cmd}'"
} else {
ret = sh returnStdout: true, script: "${cmd}"
}
ret = ret.trim()
return ret
}
#/*
# * 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
#
# Required Python Package
# pexpect
#---------------------------------------------------------------------
#-----------------------------------------------------------
# Import
#-----------------------------------------------------------
import logging
import sshconnection as SSH
import html
import os
import re
import time
import sys
class ClusterDeploy:
def __init__(self):
self.eNBIPAddress = ""
self.eNBUserName = ""
self.eNBPassword = ""
self.OCUserName = ""
self.OCPassword = ""
self.OCProjectName = ""
self.sourceCodePath = "/tmp/CI-CN5G-FED-RHEL8"
self.imageTags = ""
self.mode = ""
#-----------------$
#PUBLIC Methods$
#-----------------$
def Deploy_5gcn(self):
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
lPassWord = self.eNBPassword
lSourcePath = self.sourceCodePath
ocUserName = self.OCUserName
ocPassword = self.OCPassword
ocProjectName = self.OCProjectName
limageTags = self.imageTags
if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '' or ocUserName == '' or ocPassword == '' or ocProjectName == '' or limageTags == '':
sys.exit('Insufficient Parameter')
logging.debug('Running on server: ' + lIpAddr)
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
mySSH.command('cd ' + lSourcePath, '\$', 5)
images = limageTags.split(',')
for image in images:
eachImage = image.split(':')
imageName = eachImage(0)
imageTag = eachImage(1)
# Check if image is exist on the Red Hat server, before pushing it to OC cluster
mySSH.command("sudo podman image inspect --format='Size = {{.Size}} bytes' " + imageName + ":" + imageTag, '\$', 60)
if mySSH.getBefore().count('no such image') != 0:
logging.error(f'\u001B[1m No such image {imageName}]\u001B[0m')
mySSH.close()
sys.exit(-1)
else:
result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', mySSH.getBefore())
if result is not None:
imageSize = float(result.group('size'))
imageSize = imageSize / 1000
if imageSize < 1000:
logging.debug(f'\u001B[1m {imageName} size is ' + ('%.0f' % imageSize) + ' kbytes\u001B[0m')
else:
imageSize = imageSize / 1000
if imageSize < 1000:
logging.debug(f'\u001B[1m {imageName} size is ' + ('%.0f' % imageSize) + ' Mbytes\u001B[0m')
else:
imageSize = imageSize / 1000
logging.debug(f'\u001B[1m {imageName} is ' + ('%.3f' % imageSize) + ' Gbytes\u001B[0m')
else:
logging.debug(f'{imageName} size is unknown')
# logging to OC Cluster and then switch to corresponding project
mySSH.command(f'oc login -u {ocUserName} -p {ocPassword}', '\$', 6)
if mySSH.getBefore().count('Login successful.') == 0:
logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m')
mySSH.close()
sys.exit(-1)
else:
logging.debug('\u001B[1m Login to OC Cluster Successfully\u001B[0m')
mySSH.command(f'oc project {ocProjectName}', '\$', 6)
if mySSH.getBefore().count(f'Already on project "{ocProjectName}"') == 0 and mySSH.getBefore().count(f'Now using project "{self.OCProjectName}"') == 0:
logging.error(f'\u001B[1m Unable to access OC project {ocProjectName}\u001B[0m')
mySSH.close()
sys.exit(-1)
else:
logging.debug(f'\u001B[1m Now using project {ocProjectName}\u001B[0m')
# Tag the image and push to the OC cluster
mySSH.command('oc whoami -t | sudo podman login -u ' + ocUserName + ' --password-stdin https://default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/ --tls-verify=false', '\$', 6)
if mySSH.getBefore().count('Login Succeeded!') == 0:
logging.error('\u001B[1m Podman Login to OC Cluster Registry Failed\u001B[0m')
mySSH.close()
sys.exit(-1)
else:
logging.debug('\u001B[1m Podman Login to OC Cluster Registry Successfully\u001B[0m')
for image in images:
imageName = image(0)
imageTag = image(1)
mySSH.command(f'oc create -f openshift/{imageName}-image-stream.yml', '\$', 6)
if mySSH.getBefore().count('(AlreadyExists):') == 0 and mySSH.getBefore().count('created') == 0:
logging.error(f'\u001B[1m Image Stream "{imageName}" Creation Failed on OC Cluster {ocProjectName}\u001B[0m')
mySSH.close()
sys.exit(-1)
else:
logging.debug(f'\u001B[1m Image Stream "{imageName}" created on OC project {ocProjectName}\u001B[0m')
mySSH.command(f'sudo podman tag {imageName}:{imageTag} default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/{imageName}:{imageTag}', '\$', 6)
mySSH.command(f'sudo podman push default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/{imageName}:{imageTag} --tls-verify=false', '\$', 60)
if mySSH.getBefore().count('Storing signatures') == 0:
logging.error(f'\u001B[1m Image "{imageName}" push to OC Cluster Registry Failed\u001B[0m')
mySSH.close()
sys.exit(-1)
else:
logging.debug(f'\u001B[1m Image "{imageName}" push to OC Cluster Registry Successfully\u001B[0m')
passPods = 0
# Using helm charts deployment
time.sleep(5)
for image in images:
eachImage = image.split(':')
imageName = eachImage(0)
imageTag = eachImage(1)
mySSH.command(f'sed -i -e "s#TAG#{imageTag}#g" ./charts/oai-5gcn/charts/{imageName}/values.yaml', '\$', 6)
if imageName == 'oai-nrf':
nameSufix = 'nrf'
elif imageName == 'oai-amf':
nameSufix = 'amf'
elif imageName == 'oai-smf':
nameSufix = 'smf'
elif imageName == 'oai-spgwu-tiny':
nameSufix = 'spgwu'
mySSH.command(f'helm install {imageName} ./charts/{imageName}/ | tee -a archives/5gcn_helm_summary.txt 2>&1', '\$', 6)
if mySSH.getBefore().count('STATUS: deployed') == 0:
logging.error(f'\u001B[1m Deploying "{imageName}" Failed using helm chart on OC Cluster\u001B[0m')
else:
logging.debug(f'\u001B[1m Deployed "{imageName}" Successfully using helm chart\u001B[0m')
time.sleep(60)
mySSH.command(f'oc get pods -o wide -l app.kubernetes.io/name={imageName} | tee -a archives/5gcn_pods_summary.txt', '\$', 6, resync=True)
podName = re.findall(f'{imageName}[\S\d\w]+', mySSH.getBefore())
isRunning = False
count = 0
while count < 2 and isRunning == False:
time.sleep(60)
mySSH.command(f'oc exec {podName} -c {nameSufix} -it -- ps aux', '\$', 6, resync=True)
if mySSH.getBefore().count(f'oai_{nameSufix}') != 0:
logging.debug(f'\u001B[1m POD "{imageName}" Service Running Sucessfully\u001B[0m')
isRunning = True
passPods += 1
count +=1
if isRunning == False:
logging.error(f'\u001B[1m POD "{imageName}" Service Running FAILED \u001B[0m')
if passPods == 4:
logging.debug(f'\u001B[1m Deployment: OK \u001B[0m')
else:
logging.error(f'\u001B[1m Deployment: KO \u001B[0m')
self.UnDeploy_5gcn()
self.AnalyzeLogFile_5gcn()
sys.exit(-1)
self.AnalyzeLogFile_5gcn()
def UnDeploy_5gcn(self):
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
mySSH.command('cd ' + lSourcePath, '\$', 5)
logging.debug('\u001B[1m UnDeploying the 5gcn\u001B[0m')
# logging to OC Cluster and then switch to corresponding project
mySSH.command(f'oc login -u {ocUserName} -p {ocPassword}', '\$', 6)
if mySSH.getBefore().count('Login successful.') == 0:
logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m')
mySSH.close()
sys.exit(-1)
else:
logging.debug('\u001B[1m Login to OC Cluster Successfully\u001B[0m')
mySSH.command(f'oc project {ocProjectName}', '\$', 6)
if mySSH.getBefore().count(f'Already on project "{ocProjectName}"') == 0 and mySSH.getBefore().count(f'Now using project "{self.OCProjectName}"') == 0:
logging.error(f'\u001B[1m Unable to access OC project {ocProjectName}\u001B[0m')
mySSH.close()
sys.exit(-1)
else:
logging.debug(f'\u001B[1m Now using project {ocProjectName}\u001B[0m')
# UnDeploy the 5gcn pods
images = self.imageTags.split(',')
for image in images:
eachImage = image.split(':')
imageName = eachImage(0)
imageTag = eachImage(1)
mySSH.command(f'helm uninstall {imageName} | tee -a archives/5gcn_helm_summary.txt 2>&1', '\$', 6)
if mySSH.getBefore().count(f'release "{imageName}" uninstalled') == 0 and mySSH.getBefore().count('release: not found') == 0:
logging.error(f'\u001B[1m UnDeploying "{imageName}" Failed using helm chart on OC Cluster\u001B[0m')
else:
logging.debug(f'\u001B[1m UnDeployed "{imageName}" Successfully on OC Cluster\u001B[0m')
# Delete images and imagestream
mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/{imageName}:{imageTag}', '\$', 6)
mySSH.command(f'oc delete is {imageName}', '\$', 6)
logging.debug(f'\u001B[1m Deleted the "{imageName}" Image and ImageStream\u001B[0m')
mySSH.command('oc logout', '\$', 6)
mySSH.close()
self.AnalyzeLogFile_5gcn()
def AnalyzeLogFile_5gcn(self):
pass
#--------------------------------------------------------------------------------------------------------
#
# Start of main
#
#--------------------------------------------------------------------------------------------------------
CN = ClusterDeploy()
argvs = sys.argv
argc = len(argvs)
while len(argvs) > 1:
myArgv = argvs.pop(1)
if re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE)
CN.mode = matchReg.group(1)
elif re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
CN.eNBIPAddress = matchReg.group(1)
elif re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE)
CN.eNBUserName = matchReg.group(1)
elif re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE)
CN.eNBPassword = matchReg.group(1)
elif re.match('^\-\-OCUserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-OCUserName=(.+)$', myArgv, re.IGNORECASE)
CN.OCUserName = matchReg.group(1)
elif re.match('^\-\-OCPassword=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-OCPassword=(.+)$', myArgv, re.IGNORECASE)
CN.OCPassword = matchReg.group(1)
elif re.match('^\-\-OCProjectName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-OCProjectName=(.+)$', myArgv, re.IGNORECASE)
CN.OCProjectName = matchReg.group(1)
elif re.match('^\-\-imageTags=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-imageTags=(.+)$', myArgv, re.IGNORECASE)
CN.imageTags = matchReg.group(1)
else:
sys.exit('Invalid Parameter: ' + myArgv)
if CN.mode == 'Deploy':
CN.Deploy_5gcn()
elif CN.mode == 'UnDeploy':
CN.UnDeploy_5gcn()
\ No newline at end of file
#/*
# * 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
# */
#---------------------------------------------------------------------
# Python for CI of OAI-eNB + COTS-UE
#
# Required Python Version
# Python 3.x
#
# Required Python Package
# pexpect
#---------------------------------------------------------------------
#-----------------------------------------------------------
# Import
#-----------------------------------------------------------
import pexpect # pexpect
import logging
import time # sleep
import re
import subprocess
import sys
#-----------------------------------------------------------
# Class Declaration
#-----------------------------------------------------------
class SSHConnection():
def __init__(self):
self.ssh = ''
self.picocom_closure = False
self.ipaddress = ''
self.username = ''
self.cmd2Results = ''
def disablePicocomClosure(self):
self.picocom_closure = False
def enablePicocomClosure(self):
self.picocom_closure = True
def open(self, ipaddress, username, password):
count = 0
connect_status = False
while count < 4:
self.ssh = pexpect.spawn('ssh -o PubkeyAuthentication=no {}@{}'.format(username,ipaddress))
self.ssh.timeout = 5
self.sshresponse = self.ssh.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', 'Last login', pexpect.EOF, pexpect.TIMEOUT])
if self.sshresponse == 0:
self.ssh.sendline('yes')
self.sshresponse = self.ssh.expect(['password:', username + '@'])
if self.sshresponse == 0:
self.ssh.sendline(password)
self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if self.sshresponse == 0:
count = 10
connect_status = True
else:
logging.debug('self.sshresponse = ' + str(self.sshresponse))
elif self.sshresponse == 1:
self.ssh.sendline(password)
self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if self.sshresponse == 0:
count = 10
connect_status = True
else:
logging.debug('self.sshresponse = ' + str(self.sshresponse))
elif self.sshresponse == 2:
# Checking if we are really on the remote client defined by its IP address
self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:|inet "', '\$', 5)
result = re.search(str(ipaddress), str(self.ssh.before))
if result is None:
self.close()
else:
count = 10
connect_status = True
else:
# debug output
logging.debug(str(self.ssh.before))
logging.debug('self.sshresponse = ' + str(self.sshresponse))
# adding a tempo when failure
if not connect_status:
time.sleep(1)
count += 1
if connect_status:
pass
else:
sys.exit('SSH Connection Failed')
self.ipaddress = ipaddress
self.username = username
def cde_check_value(self, commandline, expected, timeout):
logging.debug(commandline)
self.ssh.timeout = timeout
self.ssh.sendline(commandline)
expected.append(pexpect.EOF)
expected.append(pexpect.TIMEOUT)
self.sshresponse = self.ssh.expect(expected)
return self.sshresponse
def command(self, commandline, expectedline, timeout, silent=False, resync=False):
if not silent:
logging.debug(commandline)
self.ssh.timeout = timeout
# Nasty patch when pexpect output is out of sync.
# Much pronounced when running back-to-back-back oc commands
if resync:
self.ssh.send(commandline)
self.ssh.expect([commandline, pexpect.TIMEOUT])
self.ssh.send('\r\n')
self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT])
else:
self.ssh.sendline(commandline)
self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT])
if self.sshresponse == 0:
return 0
elif self.sshresponse == 1:
logging.debug('\u001B[1;37;41m Unexpected EOF \u001B[0m')
logging.debug('Expected Line : ' + expectedline)
logging.debug(str(self.ssh.before))
sys.exit(self.sshresponse)
elif self.sshresponse == 2:
logging.debug('\u001B[1;37;41m Unexpected TIMEOUT \u001B[0m')
logging.debug('Expected Line : ' + expectedline)
result = re.search('ping |iperf |picocom', str(commandline))
if result is None:
logging.debug(str(self.ssh.before))
sys.exit(self.sshresponse)
else:
return -1
else:
logging.debug('\u001B[1;37;41m Unexpected Others \u001B[0m')
logging.debug('Expected Line : ' + expectedline)
sys.exit(self.sshresponse)
def command2(self, commandline, timeout, silent=False):
if not silent:
logging.debug(commandline)
self.cmd2Results = ''
myHost = self.username + '@' + self.ipaddress
# CAUTION: THIS METHOD IMPLIES THAT THERE ARE VALID SSH KEYS
# BETWEEN THE PYTHON EXECUTOR NODE AND THE REMOTE HOST
# OTHERWISE IT WON'T WORK
lSsh = subprocess.Popen(["ssh", "%s" % myHost, commandline],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
self.cmd2Results = str(lSsh.stdout.readlines())
def close(self):
self.ssh.timeout = 5
self.ssh.sendline('exit')
self.sshresponse = self.ssh.expect([pexpect.EOF, pexpect.TIMEOUT])
self.ipaddress = ''
self.username = ''
if self.sshresponse == 0:
pass
elif self.sshresponse == 1:
if not self.picocom_closure:
logging.debug('\u001B[1;37;41m Unexpected TIMEOUT during closing\u001B[0m')
else:
logging.debug('\u001B[1;37;41m Unexpected Others during closing\u001B[0m')
def copyin(self, ipaddress, username, password, source, destination):
count = 0
copy_status = False
logging.debug('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination)
while count < 10:
scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 100)
scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0:
scp_spawn.sendline('yes')
scp_spawn.expect('password:')
scp_spawn.sendline(password)
scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0:
count = 10
copy_status = True
else:
logging.debug('1 - scp_response = ' + str(scp_response))
elif scp_response == 1:
scp_spawn.sendline(password)
scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0 or scp_response == 3:
count = 10
copy_status = True
else:
logging.debug('2 - scp_response = ' + str(scp_response))
elif scp_response == 2:
count = 10
copy_status = True
else:
logging.debug('3 - scp_response = ' + str(scp_response))
# adding a tempo when failure
if not copy_status:
time.sleep(1)
count += 1
if copy_status:
return 0
else:
return -1
def copyout(self, ipaddress, username, password, source, destination):
count = 0
copy_status = False
logging.debug('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination)
while count < 4:
scp_spawn = pexpect.spawn('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 100)
scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0:
scp_spawn.sendline('yes')
scp_spawn.expect('password:')
scp_spawn.sendline(password)
scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0:
count = 10
copy_status = True
else:
logging.debug('1 - scp_response = ' + str(scp_response))
elif scp_response == 1:
scp_spawn.sendline(password)
scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0 or scp_response == 3:
count = 10
copy_status = True
else:
logging.debug('2 - scp_response = ' + str(scp_response))
elif scp_response == 2:
count = 10
copy_status = True
else:
logging.debug('3 - scp_response = ' + str(scp_response))
# adding a tempo when failure
if not copy_status:
time.sleep(1)
count += 1
if copy_status:
pass
else:
sys.exit('SCP failed')
def getBefore(self):
return str(self.ssh.before)
#/*
# * 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
# */
#---------------------------------------------------------------------
#
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
name: oai-amf
spec:
lookupPolicy:
local: true
#/*
# * 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
# */
#---------------------------------------------------------------------
#
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
name: oai-nrf
spec:
lookupPolicy:
local: true
#/*
# * 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
# */
#---------------------------------------------------------------------
#
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
name: oai-smf
spec:
lookupPolicy:
local: true
#/*
# * 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
# */
#---------------------------------------------------------------------
#
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
name: oai-spgwu-tiny
spec:
lookupPolicy:
local: true
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment