Merge remote-tracking branch 'origin/develop-NR_SA_F1AP_5GRECORDS-abs' into NR_UE_SA

This commit is contained in:
francescomani
2021-07-14 10:35:09 +02:00
582 changed files with 18721 additions and 10036 deletions
Regular → Executable
View File
Regular → Executable
View File
+36
View File
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-physim
description: A Helm chart for physical simulators network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulators
- RAN
- 4G
- 5G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
+36
View File
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-dlsim
description: A Helm subchart for dlsim network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulator
- dlsim
- RAN
- 4G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-dlsim.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-dlsim.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-dlsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-dlsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
@@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-dlsim.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-dlsim.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-dlsim.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-dlsim.labels" -}}
helm.sh/chart: {{ include "oai-dlsim.chart" . }}
{{ include "oai-dlsim.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-dlsim.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-dlsim.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-dlsim.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-dlsim.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-dlsim.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oai-dlsim.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
labels:
{{- include "oai-dlsim.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: physim
image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: 80
name: oai-dlsim
# volumeMounts:
# - mountPath: /opt/oai-dlsim/certs
# name: certs
command: ["/bin/sh", "-c"]
args:
- >
export OPENAIR_DIR=/opt/oai-physim &&
cd cmake_targets/autotests &&
./run_exec_autotests.bash -g "015100" -q -np -b &&
echo "FINISHED" &&
sleep infinity
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.global.serviceAccountName }}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-dlsim.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
{{- if contains "ClusterIP" .Values.service.type }}
clusterIP: None
{{- end }}
ports:
- name: oai-dlsim
# Port accessible outside cluster
port: {{ .Values.service.port }}
# Port to forward to inside the pod
targetPort: {{ .Values.service.Port }}
protocol: TCP
selector:
{{- include "oai-dlsim.selectorLabels" . | nindent 4 }}
+63
View File
@@ -0,0 +1,63 @@
# Default values for oai-dlsim.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
namespace: "oaicicd-ran-tmp"
image:
registry: local
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: temp
# pullPolicy: IfNotPresent or Never or Always
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-dlsim-sa"
podSecurityContext:
runAsUser: 0
runAsGroup: 0
securityContext:
privileged: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
+36
View File
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-ldpctest
description: A Helm subchart for ldpctest network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulator
- ldpctest
- RAN
- 5G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-ldpctest.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-ldpctest.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-ldpctest.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-ldpctest.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
@@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-ldpctest.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-ldpctest.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-ldpctest.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-ldpctest.labels" -}}
helm.sh/chart: {{ include "oai-ldpctest.chart" . }}
{{ include "oai-ldpctest.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-ldpctest.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-ldpctest.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-ldpctest.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-ldpctest.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-ldpctest.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oai-ldpctest.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
labels:
{{- include "oai-ldpctest.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: physim
image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: 80
name: oai-ldpctest
# volumeMounts:
# - mountPath: /opt/oai-ldpctest/certs
# name: certs
command: ["/bin/sh", "-c"]
args:
- >
export OPENAIR_DIR=/opt/oai-physim &&
cd cmake_targets/autotests &&
./run_exec_autotests.bash -g "015102" -q -np -b &&
echo "FINISHED" &&
sleep infinity
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.global.serviceAccountName }}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-ldpctest.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
{{- if contains "ClusterIP" .Values.service.type }}
clusterIP: None
{{- end }}
ports:
- name: oai-ldpctest
# Port accessible outside cluster
port: {{ .Values.service.port }}
# Port to forward to inside the pod
targetPort: {{ .Values.service.Port }}
protocol: TCP
selector:
{{- include "oai-ldpctest.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,63 @@
# Default values for oai-ldpctest.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
namespace: "oaicicd-ran-tmp"
image:
registry: local
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: temp
# pullPolicy: IfNotPresent or Never or Always
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-ldpctest-sa"
podSecurityContext:
runAsUser: 0
runAsGroup: 0
securityContext:
privileged: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-nr-dlschsim
description: A Helm subchart for nr-dlschsim network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulator
- nr-dlschsim
- RAN
- 5G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-dlschsim.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-dlschsim.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-dlschsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-dlschsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
@@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-nr-dlschsim.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-nr-dlschsim.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-nr-dlschsim.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-nr-dlschsim.labels" -}}
helm.sh/chart: {{ include "oai-nr-dlschsim.chart" . }}
{{ include "oai-nr-dlschsim.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-nr-dlschsim.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-nr-dlschsim.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-nr-dlschsim.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-nr-dlschsim.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-dlschsim.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oai-nr-dlschsim.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
labels:
{{- include "oai-nr-dlschsim.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: physim
image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: 80
name: oai-nr-dlschsim
# volumeMounts:
# - mountPath: /opt/oai-nr-dlschsim/certs
# name: certs
command: ["/bin/sh", "-c"]
args:
- >
export OPENAIR_DIR=/opt/oai-physim &&
cd cmake_targets/autotests &&
./run_exec_autotests.bash -g "015106" -q -np -b &&
echo "FINISHED" &&
sleep infinity
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.global.serviceAccountName }}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-dlschsim.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
{{- if contains "ClusterIP" .Values.service.type }}
clusterIP: None
{{- end }}
ports:
- name: oai-nr-dlschsim
# Port accessible outside cluster
port: {{ .Values.service.port }}
# Port to forward to inside the pod
targetPort: {{ .Values.service.Port }}
protocol: TCP
selector:
{{- include "oai-nr-dlschsim.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,63 @@
# Default values for oai-nr-dlschsim.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
namespace: "oaicicd-ran-tmp"
image:
registry: local
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: temp
# pullPolicy: IfNotPresent or Never or Always
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-nr-dlschsim-sa"
podSecurityContext:
runAsUser: 0
runAsGroup: 0
securityContext:
privileged: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
+36
View File
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-nr-dlsim
description: A Helm subchart for nr-dlsim network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulator
- nr-dlsim
- RAN
- 5G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-dlsim.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-dlsim.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-dlsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-dlsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
@@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-nr-dlsim.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-nr-dlsim.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-nr-dlsim.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-nr-dlsim.labels" -}}
helm.sh/chart: {{ include "oai-nr-dlsim.chart" . }}
{{ include "oai-nr-dlsim.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-nr-dlsim.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-nr-dlsim.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-nr-dlsim.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-nr-dlsim.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-dlsim.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oai-nr-dlsim.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
labels:
{{- include "oai-nr-dlsim.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: physim
image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: 80
name: oai-nr-dlsim
# volumeMounts:
# - mountPath: /opt/oai-nr-dlsim/certs
# name: certs
command: ["/bin/sh", "-c"]
args:
- >
export OPENAIR_DIR=/opt/oai-physim &&
cd cmake_targets/autotests &&
./run_exec_autotests.bash -g "015105" -q -np -b &&
echo "FINISHED" &&
sleep infinity
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.global.serviceAccountName }}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-dlsim.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
{{- if contains "ClusterIP" .Values.service.type }}
clusterIP: None
{{- end }}
ports:
- name: oai-nr-dlsim
# Port accessible outside cluster
port: {{ .Values.service.port }}
# Port to forward to inside the pod
targetPort: {{ .Values.service.Port }}
protocol: TCP
selector:
{{- include "oai-nr-dlsim.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,63 @@
# Default values for oai-nr-dlsim.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
namespace: "oaicicd-ran-tmp"
image:
registry: local
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: temp
# pullPolicy: IfNotPresent or Never or Always
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-nr-dlsim-sa"
podSecurityContext:
runAsUser: 0
runAsGroup: 0
securityContext:
privileged: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-nr-pbchsim
description: A Helm subchart for nr-pbchsim network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulator
- nr-pbchsim
- RAN
- 5G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-pbchsim.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-pbchsim.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-pbchsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-pbchsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
@@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-nr-pbchsim.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-nr-pbchsim.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-nr-pbchsim.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-nr-pbchsim.labels" -}}
helm.sh/chart: {{ include "oai-nr-pbchsim.chart" . }}
{{ include "oai-nr-pbchsim.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-nr-pbchsim.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-nr-pbchsim.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-nr-pbchsim.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-nr-pbchsim.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-pbchsim.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oai-nr-pbchsim.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
labels:
{{- include "oai-nr-pbchsim.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: physim
image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: 80
name: oai-nr-pbchsim
# volumeMounts:
# - mountPath: /opt/oai-nr-pbchsim/certs
# name: certs
command: ["/bin/sh", "-c"]
args:
- >
export OPENAIR_DIR=/opt/oai-physim &&
cd cmake_targets/autotests &&
./run_exec_autotests.bash -g "015104" -q -np -b &&
echo "FINISHED" &&
sleep infinity
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.global.serviceAccountName }}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-pbchsim.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
{{- if contains "ClusterIP" .Values.service.type }}
clusterIP: None
{{- end }}
ports:
- name: oai-nr-pbchsim
# Port accessible outside cluster
port: {{ .Values.service.port }}
# Port to forward to inside the pod
targetPort: {{ .Values.service.Port }}
protocol: TCP
selector:
{{- include "oai-nr-pbchsim.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,63 @@
# Default values for oai-nr-pbchsim.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
namespace: "oaicicd-ran-tmp"
image:
registry: local
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: temp
# pullPolicy: IfNotPresent or Never or Always
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-nr-pbchsim-sa"
podSecurityContext:
runAsUser: 0
runAsGroup: 0
securityContext:
privileged: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-nr-prachsim
description: A Helm subchart for nr-prachsim network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulator
- nr-prachsim
- RAN
- 5G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-prachsim.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-prachsim.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-prachsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-prachsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
@@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-nr-prachsim.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-nr-prachsim.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-nr-prachsim.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-nr-prachsim.labels" -}}
helm.sh/chart: {{ include "oai-nr-prachsim.chart" . }}
{{ include "oai-nr-prachsim.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-nr-prachsim.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-nr-prachsim.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-nr-prachsim.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-nr-prachsim.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-prachsim.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oai-nr-prachsim.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
labels:
{{- include "oai-nr-prachsim.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: physim
image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: 80
name: oai-nr-prachsim
# volumeMounts:
# - mountPath: /opt/oai-nr-prachsim/certs
# name: certs
command: ["/bin/sh", "-c"]
args:
- >
export OPENAIR_DIR=/opt/oai-physim &&
cd cmake_targets/autotests &&
./run_exec_autotests.bash -g "015112" -q -np -b &&
echo "FINISHED" &&
sleep infinity
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.global.serviceAccountName }}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-prachsim.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
{{- if contains "ClusterIP" .Values.service.type }}
clusterIP: None
{{- end }}
ports:
- name: oai-nr-prachsim
# Port accessible outside cluster
port: {{ .Values.service.port }}
# Port to forward to inside the pod
targetPort: {{ .Values.service.Port }}
protocol: TCP
selector:
{{- include "oai-nr-prachsim.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,63 @@
# Default values for oai-nr-prachsim.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
namespace: "oaicicd-ran-tmp"
image:
registry: local
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: temp
# pullPolicy: IfNotPresent or Never or Always
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-nr-prachsim-sa"
podSecurityContext:
runAsUser: 0
runAsGroup: 0
securityContext:
privileged: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-nr-pucchsim
description: A Helm subchart for nr-pucchsim network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulator
- nr-pucchsim
- RAN
- 5G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-pucchsim.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-pucchsim.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-pucchsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-pucchsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
@@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-nr-pucchsim.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-nr-pucchsim.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-nr-pucchsim.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-nr-pucchsim.labels" -}}
helm.sh/chart: {{ include "oai-nr-pucchsim.chart" . }}
{{ include "oai-nr-pucchsim.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-nr-pucchsim.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-nr-pucchsim.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-nr-pucchsim.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-nr-pucchsim.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-pucchsim.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oai-nr-pucchsim.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
labels:
{{- include "oai-nr-pucchsim.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: physim
image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: 80
name: oai-nr-pucchsim
# volumeMounts:
# - mountPath: /opt/oai-nr-pucchsim/certs
# name: certs
command: ["/bin/sh", "-c"]
args:
- >
export OPENAIR_DIR=/opt/oai-physim &&
cd cmake_targets/autotests &&
./run_exec_autotests.bash -g "015109" -q -np -b &&
echo "FINISHED" &&
sleep infinity
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.global.serviceAccountName }}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-pucchsim.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
{{- if contains "ClusterIP" .Values.service.type }}
clusterIP: None
{{- end }}
ports:
- name: oai-nr-pucchsim
# Port accessible outside cluster
port: {{ .Values.service.port }}
# Port to forward to inside the pod
targetPort: {{ .Values.service.Port }}
protocol: TCP
selector:
{{- include "oai-nr-pucchsim.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,63 @@
# Default values for oai-nr-pucchsim.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
namespace: "oaicicd-ran-tmp"
image:
registry: local
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: temp
# pullPolicy: IfNotPresent or Never or Always
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-nr-pucchsim-sa"
podSecurityContext:
runAsUser: 0
runAsGroup: 0
securityContext:
privileged: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-nr-ulschsim
description: A Helm subchart for nr-ulschsim network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulator
- nr-ulschsim
- RAN
- 5G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-ulschsim.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-ulschsim.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-ulschsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-ulschsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
@@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-nr-ulschsim.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-nr-ulschsim.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-nr-ulschsim.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-nr-ulschsim.labels" -}}
helm.sh/chart: {{ include "oai-nr-ulschsim.chart" . }}
{{ include "oai-nr-ulschsim.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-nr-ulschsim.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-nr-ulschsim.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-nr-ulschsim.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-nr-ulschsim.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-ulschsim.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oai-nr-ulschsim.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
labels:
{{- include "oai-nr-ulschsim.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: physim
image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: 80
name: oai-nr-ulschsim
# volumeMounts:
# - mountPath: /opt/oai-nr-ulschsim/certs
# name: certs
command: ["/bin/sh", "-c"]
args:
- >
export OPENAIR_DIR=/opt/oai-physim &&
cd cmake_targets/autotests &&
./run_exec_autotests.bash -g "015108" -q -np -b &&
echo "FINISHED" &&
sleep infinity
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.global.serviceAccountName }}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-ulschsim.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
{{- if contains "ClusterIP" .Values.service.type }}
clusterIP: None
{{- end }}
ports:
- name: oai-nr-ulschsim
# Port accessible outside cluster
port: {{ .Values.service.port }}
# Port to forward to inside the pod
targetPort: {{ .Values.service.Port }}
protocol: TCP
selector:
{{- include "oai-nr-ulschsim.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,63 @@
# Default values for oai-nr-ulschsim.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
namespace: "oaicicd-ran-tmp"
image:
registry: local
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: temp
# pullPolicy: IfNotPresent or Never or Always
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-nr-ulschsim-sa"
podSecurityContext:
runAsUser: 0
runAsGroup: 0
securityContext:
privileged: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
+36
View File
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-nr-ulsim
description: A Helm subchart for nr-ulsim network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulator
- nr-ulsim
- RAN
- 5G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-ulsim.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-ulsim.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-ulsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-ulsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
@@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-nr-ulsim.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-nr-ulsim.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-nr-ulsim.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-nr-ulsim.labels" -}}
helm.sh/chart: {{ include "oai-nr-ulsim.chart" . }}
{{ include "oai-nr-ulsim.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-nr-ulsim.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-nr-ulsim.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-nr-ulsim.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-nr-ulsim.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-ulsim.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oai-nr-ulsim.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
labels:
{{- include "oai-nr-ulsim.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: physim
image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: 80
name: oai-nr-ulsim
# volumeMounts:
# - mountPath: /opt/oai-nr-ulsim/certs
# name: certs
command: ["/bin/sh", "-c"]
args:
- >
export OPENAIR_DIR=/opt/oai-physim &&
cd cmake_targets/autotests &&
./run_exec_autotests.bash -g "015111" -q -np -b &&
echo "FINISHED" &&
sleep infinity
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.global.serviceAccountName }}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-nr-ulsim.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
{{- if contains "ClusterIP" .Values.service.type }}
clusterIP: None
{{- end }}
ports:
- name: oai-nr-ulsim
# Port accessible outside cluster
port: {{ .Values.service.port }}
# Port to forward to inside the pod
targetPort: {{ .Values.service.Port }}
protocol: TCP
selector:
{{- include "oai-nr-ulsim.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,63 @@
# Default values for oai-nr-ulsim.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
namespace: "oaicicd-ran-tmp"
image:
registry: local
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: temp
# pullPolicy: IfNotPresent or Never or Always
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-nr-ulsim-sa"
podSecurityContext:
runAsUser: 0
runAsGroup: 0
securityContext:
privileged: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-polartest
description: A Helm subchart for polartest network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulator
- polartest
- RAN
- 4G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-polartest.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-polartest.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-polartest.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-polartest.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
@@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-polartest.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-polartest.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-polartest.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-polartest.labels" -}}
helm.sh/chart: {{ include "oai-polartest.chart" . }}
{{ include "oai-polartest.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-polartest.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-polartest.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-polartest.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-polartest.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-polartest.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oai-polartest.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
labels:
{{- include "oai-polartest.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: physim
image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: 80
name: oai-polartest
# volumeMounts:
# - mountPath: /opt/oai-polartest/certs
# name: certs
command: ["/bin/sh", "-c"]
args:
- >
export OPENAIR_DIR=/opt/oai-physim &&
cd cmake_targets/autotests &&
./run_exec_autotests.bash -g "015103" -q -np -b &&
echo "FINISHED" &&
sleep infinity
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.global.serviceAccountName }}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-polartest.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
{{- if contains "ClusterIP" .Values.service.type }}
clusterIP: None
{{- end }}
ports:
- name: oai-polartest
# Port accessible outside cluster
port: {{ .Values.service.port }}
# Port to forward to inside the pod
targetPort: {{ .Values.service.Port }}
protocol: TCP
selector:
{{- include "oai-polartest.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,63 @@
# Default values for oai-polartest.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
namespace: "oaicicd-ran-tmp"
image:
registry: local
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: temp
# pullPolicy: IfNotPresent or Never or Always
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-polartest-sa"
podSecurityContext:
runAsUser: 0
runAsGroup: 0
securityContext:
privileged: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-smallblocktest
description: A Helm subchart for smallblocktest network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulator
- smallblocktest
- RAN
- 4G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-smallblocktest.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-smallblocktest.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-smallblocktest.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-smallblocktest.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
@@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-smallblocktest.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-smallblocktest.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-smallblocktest.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-smallblocktest.labels" -}}
helm.sh/chart: {{ include "oai-smallblocktest.chart" . }}
{{ include "oai-smallblocktest.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-smallblocktest.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-smallblocktest.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-smallblocktest.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-smallblocktest.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-smallblocktest.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oai-smallblocktest.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
labels:
{{- include "oai-smallblocktest.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: physim
image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: 80
name: oai-smallblock
# volumeMounts:
# - mountPath: /opt/oai-smallblocktest/certs
# name: certs
command: ["/bin/sh", "-c"]
args:
- >
export OPENAIR_DIR=/opt/oai-physim &&
cd cmake_targets/autotests &&
./run_exec_autotests.bash -g "015107" -q -np -b &&
echo "FINISHED" &&
sleep infinity
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.global.serviceAccountName }}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-smallblocktest.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
{{- if contains "ClusterIP" .Values.service.type }}
clusterIP: None
{{- end }}
ports:
- name: oai-smallblocktest
# Port accessible outside cluster
port: {{ .Values.service.port }}
# Port to forward to inside the pod
targetPort: {{ .Values.service.Port }}
protocol: TCP
selector:
{{- include "oai-smallblocktest.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,63 @@
# Default values for oai-smallblocktest.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
namespace: "oaicicd-ran-tmp"
image:
registry: local
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: temp
# pullPolicy: IfNotPresent or Never or Always
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-smallblocktest-sa"
podSecurityContext:
runAsUser: 0
runAsGroup: 0
securityContext:
privileged: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
+36
View File
@@ -0,0 +1,36 @@
apiVersion: v1
name: oai-ulsim
description: A Helm subchart for ulsim network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: v1
keywords:
- Physical Simulator
- ulsim
- RAN
- 4G
sources:
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-ulsim.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-ulsim.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-ulsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-ulsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
@@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-ulsim.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-ulsim.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-ulsim.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-ulsim.labels" -}}
helm.sh/chart: {{ include "oai-ulsim.chart" . }}
{{ include "oai-ulsim.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-ulsim.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-ulsim.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-ulsim.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-ulsim.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-ulsim.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oai-ulsim.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
labels:
{{- include "oai-ulsim.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: physim
image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: 80
name: oai-ulsim
# volumeMounts:
# - mountPath: /opt/oai-ulsim/certs
# name: certs
command: ["/bin/sh", "-c"]
args:
- >
export OPENAIR_DIR=/opt/oai-physim &&
cd cmake_targets/autotests &&
./run_exec_autotests.bash -g "015101" -q -np -b &&
echo "FINISHED" &&
sleep infinity
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.global.serviceAccountName }}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "oai-ulsim.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
{{- if contains "ClusterIP" .Values.service.type }}
clusterIP: None
{{- end }}
ports:
- name: oai-ulsim
# Port accessible outside cluster
port: {{ .Values.service.port }}
# Port to forward to inside the pod
targetPort: {{ .Values.service.Port }}
protocol: TCP
selector:
{{- include "oai-ulsim.selectorLabels" . | nindent 4 }}
+63
View File
@@ -0,0 +1,63 @@
# Default values for oai-ulsim.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
namespace: "oaicicd-ran-tmp"
image:
registry: local
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: temp
# pullPolicy: IfNotPresent or Never or Always
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-ulsim-sa"
podSecurityContext:
runAsUser: 0
runAsGroup: 0
securityContext:
privileged: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
+12
View File
@@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: {{ .Chart.Name }}-{{ .Values.global.namespace }}-rbac
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: {{ .Values.global.serviceAccountName }}
namespace: {{ .Values.global.namespace }}
@@ -0,0 +1,4 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.global.serviceAccountName }}
+84
View File
@@ -0,0 +1,84 @@
# Default values for oai-physim.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
global:
serviceAccountName: oai-physim-sa
namespace: "oaicicd-ran-tmp"
image:
repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
version: TAG
## Declaring values specific to coressponding physim to overwrite
dlsim:
replicaCount: 1
service:
type: ClusterIP
port: 80
ulsim:
replicaCount: 1
service:
type: ClusterIP
port: 80
ldpctest:
replicaCount: 1
service:
type: ClusterIP
port: 80
polartest:
replicaCount: 1
service:
type: ClusterIP
port: 80
nr-pbchsim:
replicaCount: 1
service:
type: ClusterIP
port: 80
nr-dlsim:
replicaCount: 1
service:
type: ClusterIP
port: 80
nr-dlschsim:
replicaCount: 1
service:
type: ClusterIP
port: 80
smallblocktest:
replicaCount: 1
service:
type: ClusterIP
port: 80
nr-ulschsim:
replicaCount: 1
service:
type: ClusterIP
port: 80
nr-pucchsim:
replicaCount: 1
service:
type: ClusterIP
port: 80
nr-ulsim:
replicaCount: 1
service:
type: ClusterIP
port: 80
nr-prachsim:
replicaCount: 1
service:
type: ClusterIP
port: 80
+24
View File
@@ -176,6 +176,30 @@ pipeline {
} }
} }
} }
stage ("Image Test Processes") {
parallel {
stage ("Physical Simulators") {
when { expression {doMandatoryTests} }
steps {
script {
triggerSlaveJob ('RAN-PhySim-Cluster', 'Test-Physim-Cluster')
}
}
post {
always {
script {
finalizeSlaveJob('RAN-PhySim-Cluster')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
}
}
} }
post { post {
always { always {
+9 -55
View File
@@ -30,8 +30,6 @@ def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) {
} }
} }
def doFlexranCtrlTest = false
// Location of the executor node // Location of the executor node
def nodeExecutor = params.nodeExecutor def nodeExecutor = params.nodeExecutor
@@ -66,9 +64,6 @@ pipeline {
echo "Platform is ${env.TESTPLATFORM_OWNER}" echo "Platform is ${env.TESTPLATFORM_OWNER}"
} }
if (params.FlexRanRtcGitLabRepository_Credentials != null) {
doFlexranCtrlTest = true
}
if (fileExists("flexran")) { if (fileExists("flexran")) {
sh "rm -Rf flexran > /dev/null 2>&1" sh "rm -Rf flexran > /dev/null 2>&1"
} }
@@ -141,15 +136,13 @@ pipeline {
// For the moment, there is no fail criteria. Just a notification of number of files that do not follow // For the moment, there is no fail criteria. Just a notification of number of files that do not follow
sh "./ci-scripts/checkCodingFormattingRules.sh" sh "./ci-scripts/checkCodingFormattingRules.sh"
} }
if (doFlexranCtrlTest && doMandatoryTests) { // With Mosaic 5G being part of OSA and making all it's repositories public
// No need to pass credentials to clone flexran-rtc
if (doMandatoryTests) {
sh "mkdir flexran" sh "mkdir flexran"
dir ('flexran') { dir ('flexran') {
withCredentials([ sh "git clone https://gitlab.eurecom.fr/flexran/flexran-rtc.git . > ../git_clone.log 2>&1"
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.FlexRanRtcGitLabRepository_Credentials}", usernameVariable: 'git_username', passwordVariable: 'git_password'] sh "git checkout develop >> ../git_clone.log 2>&1"
]) {
sh "git clone https://${git_username}:${git_password}@gitlab.eurecom.fr/flexran/flexran-rtc.git . > ../git_clone.log 2>&1"
sh "git checkout develop >> ../git_clone.log 2>&1"
}
sh "zip -r -qq flexran.zip ." sh "zip -r -qq flexran.zip ."
} }
} }
@@ -196,16 +189,6 @@ pipeline {
} }
} }
stage ("Start VM -- phy-sim") {
steps {
lock (vmResource) {
timeout (time: 5, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
}
}
}
}
stage ("Start VM -- enb-ethernet") { stage ("Start VM -- enb-ethernet") {
steps { steps {
lock (vmResource) { lock (vmResource) {
@@ -255,15 +238,6 @@ pipeline {
} }
} }
} }
stage ("Build physical simulators") {
steps {
gitlabCommitStatus(name: "Build phy-sim") {
timeout (time: 45, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
}
}
stage ("Build eNB-ethernet") { stage ("Build eNB-ethernet") {
steps { steps {
gitlabCommitStatus(name: "Build eNB-ethernet") { gitlabCommitStatus(name: "Build eNB-ethernet") {
@@ -296,9 +270,9 @@ pipeline {
script { script {
dir ('archives') { dir ('archives') {
if (fileExists('red_hat')) { if (fileExists('red_hat')) {
sh "zip -r -qq vm_build_logs.zip basic_sim phy_sim enb_eth ue_eth gnb_usrp nr_ue_usrp red_hat" sh "zip -r -qq vm_build_logs.zip basic_sim enb_eth ue_eth gnb_usrp nr_ue_usrp red_hat"
} else { } else {
sh "zip -r -qq vm_build_logs.zip basic_sim phy_sim enb_eth ue_eth gnb_usrp nr_ue_usrp" sh "zip -r -qq vm_build_logs.zip basic_sim enb_eth ue_eth gnb_usrp nr_ue_usrp"
} }
} }
if(fileExists('archives/vm_build_logs.zip')) { if(fileExists('archives/vm_build_logs.zip')) {
@@ -332,29 +306,9 @@ pipeline {
parallel { parallel {
stage ("VM-based tests") { stage ("VM-based tests") {
stages { stages {
stage ("Test physical simulators") {
when {
expression {doMandatoryTests}
}
steps {
lock (vmResource) {
script {
timeout (time: 90, unit: 'MINUTES') {
try {
gitlabCommitStatus(name: "Test phy-sim") {
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
}
}
}
}
}
}
stage ("Build Flexran Controller") { stage ("Build Flexran Controller") {
when { when {
expression {doFlexranCtrlTest && doMandatoryTests} expression {doMandatoryTests}
} }
steps { steps {
lock (vmResource) { lock (vmResource) {
@@ -716,7 +670,7 @@ pipeline {
script { script {
if (doMandatoryTests) { if (doMandatoryTests) {
dir ('archives') { dir ('archives') {
sh "if [ -d basic_sim/test ] || [ -d phy_sim/test ] || [ -d l2_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi" sh "if [ -d basic_sim/test ] || [ -d rf_sim/test ] || [ -d l2_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi"
} }
if(fileExists('archives/vm_tests_logs.zip')) { if(fileExists('archives/vm_tests_logs.zip')) {
archiveArtifacts artifacts: 'archives/vm_tests_logs.zip' archiveArtifacts artifacts: 'archives/vm_tests_logs.zip'
+233
View File
@@ -0,0 +1,233 @@
#!/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 pythonExecutor = params.pythonExecutor
// Location of the test XML file to be run
def testXMLFile = params.pythonTestXmlFile
def mainPythonAllXmlFiles = ""
def buildStageStatus = true
// Name of the test stage
def testStageName = params.pipelineTestStageName
// Name of the resource
def ciEpcResource = params.epcResource
// Global Parameters. Normally they should be populated when the master job
// triggers the slave job with parameters
def eNB_Repository
def eNB_Branch
def eNB_CommitID
def eNB_AllowMergeRequestProcess = false
def eNB_TargetBranch
// Flags
def scmEvent = false
def upstreamEvent = false
//-------------------------------------------------------------------------------
// Pipeline start
pipeline {
agent {
label pythonExecutor
}
options {
disableConcurrentBuilds()
timestamps()
ansiColor('xterm')
lock(ciEpcResource)
}
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
// It is already to late to check it
if (params.pythonExecutor != null) {
echo "eNB CI executor node : ${pythonExecutor}"
}
// If not present picking a default Stage Name
if (params.pipelineTestStageName == null) {
// picking default
testStageName = 'Template Test Stage'
}
if (params.smartphonesResource == null) {
allParametersPresent = false
}
if (params.eNB_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB_Credentials == null) {
allParametersPresent = false
}
// the following 4 parameters should be pushed by the master trigger
// if not present, take the job GIT variables (used for developing)
if (params.eNB_Repository == null) {
eNB_Repository = env.GIT_URL
} else {
eNB_Repository = params.eNB_Repository
}
echo "eNB_Repository : ${eNB_Repository}"
if (params.eNB_Branch == null) {
eNB_Branch = env.GIT_BRANCH
} else {
eNB_Branch = params.eNB_Branch
}
echo "eNB_Branch : ${eNB_Branch}"
if (params.eNB_CommitID == null) {
eNB_CommitID = env.GIT_COMMIT
} else {
eNB_CommitID = params.eNB_CommitID
}
echo "eNB_CommitID : ${eNB_CommitID}"
if (params.eNB_mergeRequest != null) {
eNB_AllowMergeRequestProcess = params.eNB_mergeRequest
if (eNB_AllowMergeRequestProcess) {
if (params.eNB_TargetBranch != null) {
eNB_TargetBranch = params.eNB_TargetBranch
} else {
eNB_TargetBranch = 'develop'
}
echo "eNB_TargetBranch : ${eNB_TargetBranch}"
}
}
if (params.EPC_IPAddress == null) {
allParametersPresent = false
}
if (params.EPC_Type == null) {
allParametersPresent = false
}
if (params.EPC_SourceCodePath == null) {
allParametersPresent = false
}
if (params.EPC_Credentials == null) {
allParametersPresent = false
}
if (params.ADB_IPAddress == null) {
allParametersPresent = false
}
if (params.ADB_Credentials == null) {
allParametersPresent = false
}
if (params.OC_Credentials == null) {
allParametersPresent = false
}
if (params.OC_ProjectName == null) {
allParametersPresent = false
}
if (allParametersPresent) {
echo "All parameters are present"
if (eNB_AllowMergeRequestProcess) {
sh "git fetch"
sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest"
} else {
sh "git fetch"
sh "git checkout -f ${eNB_CommitID}"
}
} else {
echo "Some parameters are missing"
sh "./ci-scripts/fail.sh"
}
}
}
}
stage ("Deploy and Test") {
steps {
script {
dir ('ci-scripts') {
echo "\u2705 \u001B[32m${testStageName}\u001B[0m"
// If not present picking a default XML file
if (params.pythonTestXmlFile == null) {
// picking default
testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml'
echo "Test XML file(default): ${testXMLFile}"
mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " "
} else {
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " "
echo "Test XML file : ${xmlFile}"
}
}
}
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password']
]) {
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
try {
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}"
} catch (Exception e) {
currentBuild.result = 'FAILURE'
buildStageStatus = false
}
}
}
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
}
}
}
}
}
stage ("Log Collection") {
steps {
script {
dir ('ci-scripts') {
// Zipping all archived log files
sh "zip -r -qq physim_deploytest_logs_${env.BUILD_ID}.zip physim_test_logs_*/*"
sh "rm -rf physim_test_logs_*/"
if (fileExists("physim_deploytest_logs_${env.BUILD_ID}.zip")) {
archiveArtifacts artifacts: "physim_deploytest_logs_${env.BUILD_ID}.zip"
}
if (fileExists("test_results.html")) {
sh "mv test_results.html test_results-${env.JOB_NAME}.html"
sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
archiveArtifacts artifacts: "test_results-${env.JOB_NAME}.html"
}
}
}
}
}
}
}
@@ -0,0 +1,304 @@
#!/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
*/
// Template Jenkins Declarative Pipeline script to run Test w/ RF HW
// Location of the python executor node shall be in the same subnet as the others servers
def pythonExecutor = params.pythonExecutor
// Location of the test XML file to be run
def testXMLFile = params.pythonTestXmlFile
def mainPythonAllXmlFiles = ""
def buildStageStatus = true
// Name of the test stage
def testStageName = params.pipelineTestStageName
// Name of the phone resource
def ciSmartPhonesResource1 = params.SmartPhonesResource1
def ciSmartPhonesResource2 = params.SmartPhonesResource2
// Global Parameters. Populated when the master job
// triggers the slave job with parameters
def eNB_Repository = "https://gitlab.eurecom.fr/oai/openairinterface5g.git"
def eNB_Branch = "develop"
def eNB_CommitID
def eNB_AllowMergeRequestProcess = false
def eNB_TargetBranch = "develop"
def eNB_MR = "develop"
pipeline {
agent {
label pythonExecutor
}
options {
disableConcurrentBuilds()
ansiColor('xterm')
lock(extra: [[resource: ciSmartPhonesResource2]], resource: ciSmartPhonesResource1)
}
stages {
stage("Build Init") {
steps {
script {
//retrieve latest commit ID from branch
latest_commit_from_branch= sh returnStdout: true, script: 'git log -1 origin/${eNB_Branch} | grep commit'
echo "Branch ${eNB_Branch}"
echo "${latest_commit_from_branch}"
tmp=latest_commit_from_branch.split()
echo "${tmp}"
eNB_CommitID = tmp[1]
echo "eNB_CommitID ${eNB_CommitID}"
// update the build name and description
buildName "${params.eNB_MR}"
buildDescription "Commit : ${eNB_CommitID}"
}
}
}
stage ("Verify Parameters") {
steps {
script {
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
def allParametersPresent = true
// It is already to late to check it
if (params.pythonExecutor != null) {
echo "eNB CI executor node : ${pythonExecutor}"
}
// If not present picking a default Stage Name
if (params.pipelineTestStageName == null) {
// picking default
testStageName = 'Template Test Stage'
}
if (params.SmartPhonesResource1 == null) {
allParametersPresent = false
}
if (params.SmartPhonesResource2 == null) {
allParametersPresent = false
}
// 1st eNB parameters
if (params.eNB_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB_Credentials == null) {
allParametersPresent = false
}
// 2nd eNB parameters
if (params.eNB1_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB1_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB1_Credentials == null) {
allParametersPresent = false
}
// 3rd eNB parameters
if (params.eNB2_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB2_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB2_Credentials == null) {
allParametersPresent = false
}
// the following 4 parameters should be pushed by the master trigger
// if not present, take the job GIT variables (used for developing)
if (params.eNB_Repository == null) {
eNB_Repository = env.GIT_URL
} else {
eNB_Repository = params.eNB_Repository
}
echo "eNB_Repository : ${eNB_Repository}"
if (params.eNB_Branch == null) {
eNB_Branch = env.GIT_BRANCH
} else {
eNB_Branch = params.eNB_Branch
}
echo "eNB_Branch : ${eNB_Branch}"
//if (params.eNB_CommitID == null) {
// eNB_CommitID = env.GIT_COMMIT
//} else {
// eNB_CommitID = params.eNB_CommitID
//}
echo "eNB_CommitID : ${eNB_CommitID}"
if (params.eNB_AllowMergeRequestProcess!= null) {
eNB_AllowMergeRequestProcess = params.eNB_AllowMergeRequestProcess
if (eNB_AllowMergeRequestProcess) {
if (params.eNB_TargetBranch != null) {
eNB_TargetBranch = params.eNB_TargetBranch
} else {
eNB_TargetBranch = 'develop'
}
echo "eNB_TargetBranch : ${eNB_TargetBranch}"
}
}
if (params.EPC_IPAddress == null) {
allParametersPresent = false
}
if (params.EPC_Type == null) {
allParametersPresent = false
}
if (params.EPC_SourceCodePath == null) {
allParametersPresent = false
}
if (params.EPC_Credentials == null) {
allParametersPresent = false
}
if (params.ADB_IPAddress == null) {
allParametersPresent = false
}
if (params.ADB_Credentials == null) {
allParametersPresent = false
}
if (allParametersPresent) {
echo "All parameters are present"
if (eNB_AllowMergeRequestProcess) {
sh "git fetch"
sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest"
} else {
sh "git fetch"
sh "git checkout -f ${eNB_CommitID}"
}
} else {
echo "Some parameters are missing"
sh "./ci-scripts/fail.sh"
}
}
}
}
stage ("Build and Test") {
steps {
script {
dir ('ci-scripts') {
echo "\u2705 \u001B[32m${testStageName}\u001B[0m"
// If not present picking a default XML file
if (params.pythonTestXmlFile == null) {
// picking default
testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml'
echo "Test XML file(default): ${testXMLFile}"
mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " "
} else {
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " "
echo "Test XML file : ${xmlFile}"
}
}
}
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB2_Credentials}", usernameVariable: 'eNB2_Username', passwordVariable: 'eNB2_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
]) {
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
try {
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}"
} catch (Exception e) {
currentBuild.result = 'FAILURE'
buildStageStatus = false
}
}
}
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
}
}
}
}
}
stage('Log Collection') {
parallel {
stage('Log Collection (eNB - Build)') {
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (eNB - Build)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
echo '\u2705 \u001B[32mLog Transfer (eNB - Build)\u001B[0m'
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("build.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "build.log.${env.BUILD_ID}.zip"
}
}
}
}
stage('Log Collection (eNB - Run)') {
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m'
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("enb.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "enb.log.${env.BUILD_ID}.zip"
}
if(fileExists("ci-scripts/test_results.html")) {
sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html"
sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
archiveArtifacts "test_results-${JOB_NAME}.html"
}
}
}
}
}
}
}
post {
always {
script {
if (params.pipelineZipsConsoleLog != null) {
if (params.pipelineZipsConsoleLog) {
echo "Archiving Jenkins console log"
sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true"
sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true"
if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip"
}
}
}
}
}
}
}
+2 -6
View File
@@ -33,10 +33,9 @@ def buildStageStatus = true
// Name of the test stage // Name of the test stage
def testStageName = params.pipelineTestStageName def testStageName = params.pipelineTestStageName
// Name of the phone resource // Name of the phone/server resource
def ciSmartPhonesResource1 = params.SmartPhonesResource1 def ciSmartPhonesResource1 = params.SmartPhonesResource1
def ciSmartPhonesResource2 = params.SmartPhonesResource2 def ciSmartPhonesResource2 = params.SmartPhonesResource2
def ciSmartPhonesResource3 = params.SmartPhonesResource3
// Global Parameters. Normally they should be populated when the master job // Global Parameters. Normally they should be populated when the master job
// triggers the slave job with parameters // triggers the slave job with parameters
@@ -53,7 +52,7 @@ pipeline {
options { options {
disableConcurrentBuilds() disableConcurrentBuilds()
ansiColor('xterm') ansiColor('xterm')
lock(extra: [[resource: ciSmartPhonesResource2],[resource: ciSmartPhonesResource3]], resource: ciSmartPhonesResource1) lock(extra: [[resource: ciSmartPhonesResource2]], resource: ciSmartPhonesResource1)
} }
stages { stages {
stage("Build Init") { stage("Build Init") {
@@ -85,9 +84,6 @@ pipeline {
if (params.SmartPhonesResource2 == null) { if (params.SmartPhonesResource2 == null) {
allParametersPresent = false allParametersPresent = false
} }
if (params.SmartPhonesResource3== null) {
allParametersPresent = false
}
// 1st eNB parameters // 1st eNB parameters
if (params.eNB_IPAddress == null) { if (params.eNB_IPAddress == null) {
allParametersPresent = false allParametersPresent = false
+14 -5
View File
@@ -36,8 +36,8 @@ pipeline {
stage ("Launcher") { stage ("Launcher") {
steps { steps {
script { script {
//retrieve MR that are opened nd with tag READY_TO_BE_MERGED //retrieve MR that are opened nd with tag NSA
MR_LIST= sh returnStdout: true, script: 'curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100&labels=READY_TO_BE_MERGED" | jq ".[].iid" || true ' MR_LIST= sh returnStdout: true, script: 'curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100&labels=NSA" | jq ".[].iid" || true '
echo "List of selected MR:\n${MR_LIST}" echo "List of selected MR:\n${MR_LIST}"
def MR_ARRAY = MR_LIST.split('\n') def MR_ARRAY = MR_LIST.split('\n')
//for every selected MR, retrieve the branch name and the latest commit //for every selected MR, retrieve the branch name and the latest commit
@@ -48,21 +48,30 @@ pipeline {
COMMIT_ID=COMMIT_ID.trim() COMMIT_ID=COMMIT_ID.trim()
echo "Testing NSA on : ${MR} ${SRC_BRANCH} ${COMMIT_ID}" echo "Testing NSA on : ${MR} ${SRC_BRANCH} ${COMMIT_ID}"
//calling NSA sub job //calling NSA sub job
build job: "RAN-CI-NSA-B210", wait : false, propagate : false, parameters: [ build job: "RAN-NSA-Mini-Module", wait : true, propagate : false, parameters: [
string(name: 'eNB_MR', value: String.valueOf(MR)), string(name: 'eNB_MR', value: String.valueOf(MR)),
string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)), string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)), string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)), string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE)) booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
] ]
//calling Benetel sub job //calling NSA long sub job
build job: "RAN-CI-BENETEL", wait : false, propagate : false, parameters: [ build job: "RAN-NSA-Mini-Module-Long", wait : true, propagate : false, parameters: [
string(name: 'eNB_MR', value: String.valueOf(MR)), string(name: 'eNB_MR', value: String.valueOf(MR)),
string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)), string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)), string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)), string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE)) booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
] ]
//calling NSA attach/detach job
build job: "RAN-NSA-Mini-Module-Attach-Detach", wait : true, propagate : false, parameters: [
string(name: 'eNB_MR', value: String.valueOf(MR)),
string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
]
} }
} }
} }
+19 -1
View File
@@ -41,7 +41,7 @@ import constants as CONST
#----------------------------------------------------------- #-----------------------------------------------------------
def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA): def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA,PHYSIM):
py_param_file_present = False py_param_file_present = False
@@ -81,6 +81,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA):
ldpc.ranRepository=matchReg.group(1) ldpc.ranRepository=matchReg.group(1)
CONTAINERS.ranRepository=matchReg.group(1) CONTAINERS.ranRepository=matchReg.group(1)
SCA.ranRepository=matchReg.group(1) SCA.ranRepository=matchReg.group(1)
PHYSIM.ranRepository=matchReg.group(1)
elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE)
@@ -94,6 +95,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA):
HTML.ranAllowMerge=True HTML.ranAllowMerge=True
CONTAINERS.ranAllowMerge=True CONTAINERS.ranAllowMerge=True
SCA.ranAllowMerge=True SCA.ranAllowMerge=True
PHYSIM.ranAllowMerge=True
elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE)
@@ -105,6 +107,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA):
ldpc.ranBranch=matchReg.group(1) ldpc.ranBranch=matchReg.group(1)
CONTAINERS.ranBranch=matchReg.group(1) CONTAINERS.ranBranch=matchReg.group(1)
SCA.ranBranch=matchReg.group(1) SCA.ranBranch=matchReg.group(1)
PHYSIM.ranBranch=matchReg.group(1)
elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE)
@@ -116,6 +119,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA):
ldpc.ranCommitID=matchReg.group(1) ldpc.ranCommitID=matchReg.group(1)
CONTAINERS.ranCommitID=matchReg.group(1) CONTAINERS.ranCommitID=matchReg.group(1)
SCA.ranCommitID=matchReg.group(1) SCA.ranCommitID=matchReg.group(1)
PHYSIM.ranCommitID=matchReg.group(1)
elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE)
@@ -127,6 +131,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA):
ldpc.ranTargetBranch=matchReg.group(1) ldpc.ranTargetBranch=matchReg.group(1)
CONTAINERS.ranTargetBranch=matchReg.group(1) CONTAINERS.ranTargetBranch=matchReg.group(1)
SCA.ranTargetBranch=matchReg.group(1) SCA.ranTargetBranch=matchReg.group(1)
PHYSIM.ranTargetBranch=matchReg.group(1)
elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
@@ -134,6 +139,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA):
ldpc.eNBIpAddr=matchReg.group(1) ldpc.eNBIpAddr=matchReg.group(1)
CONTAINERS.eNBIPAddress=matchReg.group(1) CONTAINERS.eNBIPAddress=matchReg.group(1)
SCA.eNBIPAddress=matchReg.group(1) SCA.eNBIPAddress=matchReg.group(1)
PHYSIM.eNBIPAddress=matchReg.group(1)
elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE): elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1IPAddress=matchReg.group(1) RAN.eNB1IPAddress=matchReg.group(1)
@@ -149,6 +155,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA):
ldpc.eNBUserName=matchReg.group(1) ldpc.eNBUserName=matchReg.group(1)
CONTAINERS.eNBUserName=matchReg.group(1) CONTAINERS.eNBUserName=matchReg.group(1)
SCA.eNBUserName=matchReg.group(1) SCA.eNBUserName=matchReg.group(1)
PHYSIM.eNBUserName=matchReg.group(1)
elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE): elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1UserName=matchReg.group(1) RAN.eNB1UserName=matchReg.group(1)
@@ -164,6 +171,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA):
ldpc.eNBPassWord=matchReg.group(1) ldpc.eNBPassWord=matchReg.group(1)
CONTAINERS.eNBPassword=matchReg.group(1) CONTAINERS.eNBPassword=matchReg.group(1)
SCA.eNBPassword=matchReg.group(1) SCA.eNBPassword=matchReg.group(1)
PHYSIM.eNBPassword=matchReg.group(1)
elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE): elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1Password=matchReg.group(1) RAN.eNB1Password=matchReg.group(1)
@@ -179,6 +187,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA):
ldpc.eNBSourceCodePath=matchReg.group(1) ldpc.eNBSourceCodePath=matchReg.group(1)
CONTAINERS.eNBSourceCodePath=matchReg.group(1) CONTAINERS.eNBSourceCodePath=matchReg.group(1)
SCA.eNBSourceCodePath=matchReg.group(1) SCA.eNBSourceCodePath=matchReg.group(1)
PHYSIM.eNBSourceCodePath=matchReg.group(1)
elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE): elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1SourceCodePath=matchReg.group(1) RAN.eNB1SourceCodePath=matchReg.group(1)
@@ -248,6 +257,15 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA):
finalStatus = matchReg.group(1) finalStatus = matchReg.group(1)
if ((finalStatus == 'true') or (finalStatus == 'True')): if ((finalStatus == 'true') or (finalStatus == 'True')):
CiTestObj.finalStatus = True CiTestObj.finalStatus = True
elif re.match('^\-\-OCUserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-OCUserName=(.+)$', myArgv, re.IGNORECASE)
PHYSIM.OCUserName = matchReg.group(1)
elif re.match('^\-\-OCPassword=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-OCPassword=(.+)$', myArgv, re.IGNORECASE)
PHYSIM.OCPassword = matchReg.group(1)
elif re.match('^\-\-OCProjectName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-OCProjectName=(.+)$', myArgv, re.IGNORECASE)
PHYSIM.OCProjectName = matchReg.group(1)
else: else:
HELP.GenericHelp(CONST.Version) HELP.GenericHelp(CONST.Version)
sys.exit('Invalid Parameter: ' + myArgv) sys.exit('Invalid Parameter: ' + myArgv)
+7
View File
@@ -0,0 +1,7 @@
#!/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 -1
View File
@@ -62,7 +62,7 @@ function build_on_vm {
echo "ARCHIVES_LOC = $ARCHIVES_LOC" echo "ARCHIVES_LOC = $ARCHIVES_LOC"
echo "BUILD_OPTIONS = $BUILD_OPTIONS" echo "BUILD_OPTIONS = $BUILD_OPTIONS"
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]]
then then
echo "This VM type is no longer supported in the pipeline framework" echo "This VM type is no longer supported in the pipeline framework"
return return
+4 -4
View File
@@ -1,15 +1,15 @@
ranRepository : https://gitlab.eurecom.fr/oai/openairinterface5g.git ranRepository : https://gitlab.eurecom.fr/oai/openairinterface5g.git
ranBranch : BRANCH_NAME ranBranch : integration_2021_wk13_a
ranCommitID : COMMIT_ID ranCommitID : 104aa7eed5d6702c1b9da663414079ef698da206
ranAllowMerge : 'true' ranAllowMerge : 'yes'
ranTargetBranch : develop ranTargetBranch : develop
steps: steps:
- InitiateHtml,none - InitiateHtml,none
- TesteNB,xml_files/fr1_multi_node_build.xml - TesteNB,xml_files/fr1_multi_node_build.xml
- TesteNB,xml_files/fr1_epc_start.xml - TesteNB,xml_files/fr1_epc_start.xml
- TesteNB,xml_files/fr1_ran_ue_base.xml #ue toggle, nodes initialize, ue toggle, ping, nodes terminate - TesteNB,xml_files/fr1_nsa_base_next.xml #ue toggle, nodes initialize, ue toggle, ping, nodes terminate
- TesteNB,xml_files/fr1_epc_closure.xml - TesteNB,xml_files/fr1_epc_closure.xml
+86
View File
@@ -0,0 +1,86 @@
# * 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
#
#---------------------------------------------------------------------
#usage example:
#sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 wup
#sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 detach
import sys
import time
import serial
class qtel_ctl:
#---------------
#private methods
#---------------
def __init__(self, usb_port_at):
self.QUECTEL_USB_PORT_AT = usb_port_at #ex : '/dev/ttyUSB2'
self.modem = serial.Serial(self.QUECTEL_USB_PORT_AT, timeout=1)
self.cmd_dict= {"wup": self.wup,"detach":self.detach}#dictionary of function pointers
def __set_modem_state(self,ser,state):
self.__send_command(ser,"AT+CFUN={}\r".format(state))
def __send_command(self,ser,com):
ser.write(com.encode())
time.sleep(0.1)
ret=[]
while ser.inWaiting()>0:
print("waiting")
msg=ser.readline()
msg=msg.decode("utf-8")
msg=msg.replace("\r","")
msg=msg.replace("\n","")
print(msg)
if msg!="":
ret.append(msg)
else:
print("msg empty")
return ret
#--------------
#public methods
#--------------
def wup(self):#sending AT+CFUN=0, then AT+CFUN=1
self.__set_modem_state(self.modem,'0')
time.sleep(3)
self.__set_modem_state(self.modem,'1')
def detach(self):#sending AT+CFUN=0
self.__set_modem_state(self.modem,'0')
if __name__ == "__main__":
#argv[1] : usb port
#argv[2] : qtel command (see function pointers dict "wup", "detach" etc ...)
command = sys.argv[2]
Module=qtel_ctl(sys.argv[1])
#calling the function to be applied
Module.cmd_dict[command]()
+32
View File
@@ -0,0 +1,32 @@
idefix:
ID: idefix
State : enabled
Kind : quectel
Process :
Name : quectel-CM
Cmd : /home/oaicicd/quectel-CM/quectel-CM -s oai.ipv4 -4
WakeupScript : ci_ctl_qtel.py /dev/ttyUSB2 wup
DetachScript : ci_ctl_qtel.py /dev/ttyUSB2 detach
PLMN : 22201
UENetwork : wwan0
HostIPAddress : 192.168.18.188
HostUsername : oaicicd
HostPassword : oaicicd
HostSourceCodePath : none
dummy:
ID: ''
State : ''
Kind : ''
Process :
Name : ''
Cmd : ''
WakeupScript : ''
DetachScript : ''
PLMN : 22201
UENetwork : wwan0
HostIPAddress : 192.168.18.188
HostUsername : oaicicd
HostPassword : oaicicd
HostSourceCodePath : none
+57
View File
@@ -0,0 +1,57 @@
# * 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
#
#---------------------------------------------------------------------
#to use isfile
import os
import sys
import logging
#to create a SSH object locally in the methods
import sshconnection
#time.sleep
import time
#to load ue infrastructure dictionary
import yaml
class InfraUE:
def __init__(self):
self.ci_ue_infra ={}
#-----------------$
#PUBLIC Methods$
#-----------------$
#This method reads the yaml file describing the multi-UE infrastructure
#and stores the infra permanently in the related class attribute self.ci_ue_infra
def Get_UE_Infra(self,ue_infra_filename):
f_yaml=ue_infra_filename
with open(f_yaml,'r') as file:
logging.debug('Loading UE infrastructure from file '+f_yaml)
#load it permanently in the class attribute
self.ci_ue_infra = yaml.load(file,Loader=yaml.FullLoader)
+30 -2
View File
@@ -88,6 +88,7 @@ class Containerize():
self.host = '' self.host = ''
self.allImagesSize = {} self.allImagesSize = {}
self.collectInfo = {} self.collectInfo = {}
#----------------------------------------------------------- #-----------------------------------------------------------
# Container management functions # Container management functions
#----------------------------------------------------------- #-----------------------------------------------------------
@@ -149,6 +150,8 @@ class Containerize():
imageNames.append(('oai-nr-ue', 'nrUE')) imageNames.append(('oai-nr-ue', 'nrUE'))
if self.host == 'Red Hat': if self.host == 'Red Hat':
imageNames.append(('oai-physim', 'phySim')) imageNames.append(('oai-physim', 'phySim'))
if self.host == 'Ubuntu':
imageNames.append(('oai-lte-ru', 'lteRU'))
if len(imageNames) == 0: if len(imageNames) == 0:
imageNames.append(('oai-enb', 'eNB')) imageNames.append(('oai-enb', 'eNB'))
@@ -161,7 +164,7 @@ class Containerize():
# on RedHat/CentOS .git extension is mandatory # on RedHat/CentOS .git extension is mandatory
result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
if result is not None: if result is not None:
full_ran_repo_name = self.ranRepository full_ran_repo_name = self.ranRepository.replace('git/', 'git')
else: else:
full_ran_repo_name = self.ranRepository + '.git' full_ran_repo_name = self.ranRepository + '.git'
mySSH.command('mkdir -p ' + lSourcePath, '\$', 5) mySSH.command('mkdir -p ' + lSourcePath, '\$', 5)
@@ -175,7 +178,7 @@ class Containerize():
mySSH.command('mkdir -p cmake_targets/log', '\$', 5) mySSH.command('mkdir -p cmake_targets/log', '\$', 5)
# if the commit ID is provided use it to point to it # if the commit ID is provided use it to point to it
if self.ranCommitID != '': if self.ranCommitID != '':
mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 5) mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
# if the branch is not develop, then it is a merge request and we need to do # if the branch is not develop, then it is a merge request and we need to do
# the potential merge. Note that merge conflicts should already been checked earlier # the potential merge. Note that merge conflicts should already been checked earlier
imageTag = 'develop' imageTag = 'develop'
@@ -335,6 +338,31 @@ class Containerize():
errorandwarnings['warnings'] = warningsNo errorandwarnings['warnings'] = warningsNo
errorandwarnings['status'] = status errorandwarnings['status'] = status
files[fil] = errorandwarnings files[fil] = errorandwarnings
# Let analyze the target image creation part
if os.path.isfile('build_log_{}/{}.log'.format(self.testCase_id,image)):
errorandwarnings = {}
with open('build_log_{}/{}.log'.format(self.testCase_id,image), mode='r') as inputfile:
startOfTargetImageCreation = False
buildStatus = False
for line in inputfile:
result = re.search('FROM .* [aA][sS] ' + image + '$', str(line))
if result is not None:
startOfTargetImageCreation = True
if startOfTargetImageCreation:
result = re.search('Successfully tagged ' + image + ':', str(line))
if result is not None:
buildStatus = True
result = re.search('COMMIT ' + image + ':', str(line))
if result is not None:
buildStatus = True
inputfile.close()
if buildStatus:
errorandwarnings['errors'] = 0
else:
errorandwarnings['errors'] = 1
errorandwarnings['warnings'] = 0
errorandwarnings['status'] = buildStatus
files['Target Image Creation'] = errorandwarnings
self.collectInfo[image] = files self.collectInfo[image] = files
if status: if status:
+103
View File
@@ -0,0 +1,103 @@
# * 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
#
#---------------------------------------------------------------------
#USAGE:
# log=Log_Mgt(IPAddress,Password,Path)
# log.LogRotation()
import re
import subprocess
import logging
import math
class Log_Mgt:
def __init__(self,IPAddress,Password,Path):
self.IPAddress=IPAddress
self.Password=Password
self.path=Path
#-----------------$
#PRIVATE# Methods$
#-----------------$
def __CheckAvailSpace(self):
HOST=self.IPAddress
COMMAND="df "+ self.path
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
s=result[1].decode('utf-8').rstrip()#result[1] is the second line with the results we are looking for
tmp=s.split()
return tmp[3] #return avail space from the line
def __GetOldestFile(self):
HOST=self.IPAddress
COMMAND="ls -rtl "+ self.path #-rtl will bring oldest file on top
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
s=result[1].decode('utf-8').rstrip()
tmp=s.split()
return tmp[8]#return filename from the line
def __AvgSize(self):
HOST=self.IPAddress
COMMAND="ls -rtl "+ self.path
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
total_size=0
for i in range(1,len(result)):
s=result[i].decode('utf-8').rstrip()
tmp=s.split()
total_size+=int(tmp[4]) #get filesize
return math.floor(total_size/(len(result)-1)) #compute average file/artifact size
#-----------------$
#PUBLIC Methods$
#-----------------$
def LogRotation(self):
avail_space =int(self.__CheckAvailSpace())*1000 #avail space in target folder, initially displayed in Gb
avg_size=self.__AvgSize() #average size of artifacts in the target folder
logging.debug("Avail Space : " + str(avail_space) + " / Artifact Avg Size : " + str(avg_size))
if avail_space < 2*avg_size: #reserved space is 2x artifact file ; oldest file will be deleted
oldestfile=self.__GetOldestFile()
HOST=self.IPAddress
COMMAND="echo " + self.Password + " | sudo -S rm "+ self.path + "/" + oldestfile
logging.debug(COMMAND)
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
else:
logging.debug("Still some space left for artifacts storage")
+175
View File
@@ -0,0 +1,175 @@
# * 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
#
#---------------------------------------------------------------------
#to use isfile
import os
import sys
import logging
#to create a SSH object locally in the methods
import sshconnection
#time.sleep
import time
import re
import subprocess
from datetime import datetime
#for log rotation mgt
import cls_log_mgt
class Module_UE:
def __init__(self,Module):
#create attributes as in the Module dictionary
for k, v in Module.items():
setattr(self, k, v)
self.UEIPAddress = ""
#dictionary linking command names and related module scripts
self.cmd_dict= {"wup": self.WakeupScript,"detach":self.DetachScript}#dictionary of function scripts
self.ue_trace=''
#-----------------$
#PUBLIC Methods$
#-----------------$
#this method checks if the specified Process is running on the server hosting the module
#if not it will be started
def CheckCMProcess(self):
HOST=self.HostIPAddress
COMMAND="ps aux | grep " + self.Process['Name'] + " | grep -v grep "
logging.debug(COMMAND)
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
if len(result)!=0:
logging.debug(self.Process['Name'] + " process found")
return True
else:#start process and check again
logging.debug(self.Process['Name'] + " process NOT found")
#starting the process
logging.debug('Starting ' + self.Process['Name'])
mySSH = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S ' + self.Process['Cmd'] + ' &','\$',5)
mySSH.close()
#checking the process
time.sleep(5)
HOST=self.HostIPAddress
COMMAND="ps aux | grep " + self.Process['Name'] + " | grep -v grep "
logging.debug(COMMAND)
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
if len(result)!=0:
logging.debug(self.Process['Name'] + " process found")
return True
else:
logging.debug(self.Process['Name'] + " process NOT found")
return False
#Generic command function, using function pointers dictionary
def Command(self,cmd):
mySSH = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
mySSH.command('echo ' + self.HostPassword + ' | sudo -S python3 ' + self.cmd_dict[cmd],'\$',10)
time.sleep(5)
logging.debug("Module "+ cmd)
mySSH.close()
#this method retrieves the Module IP address (not the Host IP address)
def GetModuleIPAddress(self):
HOST=self.HostIPAddress
response= []
tentative = 3
while (len(response)==0) and (tentative>0):
COMMAND="ip a show dev " + self.UENetwork + " | grep inet | grep " + self.UENetwork
logging.debug(COMMAND)
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
response = ssh.stdout.readlines()
tentative-=1
time.sleep(10)
if (tentative==0) and (len(response)==0):
logging.debug('\u001B[1;37;41m Module IP Address Not Found! Time expired \u001B[0m')
return -1
else: #check response
result = re.search('inet (?P<moduleipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', response[0].decode("utf-8") )
if result is not None:
if result.group('moduleipaddress') is not None:
self.UEIPAddress = result.group('moduleipaddress')
logging.debug('\u001B[1mUE Module IP Address is ' + self.UEIPAddress + '\u001B[0m')
return 0
else:
logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m')
return -1
else:
logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m')
return -1
def EnableTrace(self):
if self.ue_trace=="yes":
mySSH = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
#delete old artifacts
mySSH.command('echo ' + self.HostPassword + ' | sudo -S rm -rf ci_qlog','\$',5)
#start Trace, artifact is created in home dir
mySSH.command('echo $USER; nohup sudo -E QLog/QLog -s ci_qlog -f NR5G.cfg &','\$', 5)
mySSH.close()
def DisableTrace(self):
mySSH = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
mySSH.command('echo ' + self.HostPassword + ' | sudo -S killall --signal=SIGINT *QLog*', '\$',5)
mySSH.close()
def DisableCM(self):
mySSH = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
mySSH.command('echo ' + self.HostPassword + ' | sudo -S killall --signal SIGKILL *'+self.Process['Name']+'*', '\$', 5)
mySSH.close()
def LogCollect(self):
if self.ue_trace=="yes":
mySSH = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
#archive qlog to USB stick in /media/usb-drive/ci_qlogs with datetime suffix
now=datetime.now()
now_string = now.strftime("%Y%m%d-%H%M")
source='ci_qlog'
destination='/media/usb-drive/ci_qlogs/ci_qlog_'+now_string+'.zip'
#qlog artifact is zipped into the target folder
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S zip -r '+destination+' '+source+' &','\$', 10)
mySSH.close()
#post action : log cleaning to make sure enough space is reserved for the next run
Log_Mgt=cls_log_mgt.Log_Mgt(self.HostIPAddress, self.HostPassword, "/media/usb-drive/ci_qlogs")
Log_Mgt.LogRotation()
else:
destination=""
return destination
+372 -193
View File
@@ -54,7 +54,8 @@ import helpreadme as HELP
import constants as CONST import constants as CONST
import sshconnection import sshconnection
import cls_module_ue
import cls_ci_ueinfra #class defining the multi Ue infrastrucure
#----------------------------------------------------------- #-----------------------------------------------------------
@@ -129,6 +130,7 @@ class OaiCiTest():
self.iperf_packetloss_threshold = '' self.iperf_packetloss_threshold = ''
self.iperf_profile = '' self.iperf_profile = ''
self.iperf_options = '' self.iperf_options = ''
self.iperf_direction = ''
self.nbMaxUEtoAttach = -1 self.nbMaxUEtoAttach = -1
self.UEDevices = [] self.UEDevices = []
self.UEDevicesStatus = [] self.UEDevicesStatus = []
@@ -157,6 +159,8 @@ class OaiCiTest():
self.clean_repository = True self.clean_repository = True
self.air_interface='' self.air_interface=''
self.expectedNbOfConnectedUEs = 0 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()
def BuildOAIUE(self,HTML): def BuildOAIUE(self,HTML):
@@ -174,7 +178,7 @@ class OaiCiTest():
ue_prefix = '' ue_prefix = ''
result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
if result is not None: if result is not None:
full_ran_repo_name = self.ranRepository full_ran_repo_name = self.ranRepository.replace('git/', 'git')
else: else:
full_ran_repo_name = self.ranRepository + '.git' full_ran_repo_name = self.ranRepository + '.git'
SSH.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) SSH.command('mkdir -p ' + self.UESourceCodePath, '\$', 5)
@@ -217,7 +221,7 @@ class OaiCiTest():
# if the commit ID is provided use it to point to it # if the commit ID is provided use it to point to it
if self.ranCommitID != '': if self.ranCommitID != '':
SSH.command('git checkout -f ' + self.ranCommitID, '\$', 5) SSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
# if the branch is not develop, then it is a merge request and we need to do # if the branch is not develop, then it is a merge request and we need to do
# the potential merge. Note that merge conflicts should already been checked earlier # the potential merge. Note that merge conflicts should already been checked earlier
if self.ranAllowMerge: if self.ranAllowMerge:
@@ -364,29 +368,50 @@ class OaiCiTest():
except: except:
os.kill(os.getppid(),signal.SIGUSR1) os.kill(os.getppid(),signal.SIGUSR1)
def InitializeUE(self,HTML,COTS_UE): def InitializeUE(self,HTML,RAN,EPC, COTS_UE, InfraUE,ue_trace):
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB
HELP.GenericHelp(CONST.Version) if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
sys.exit('Insufficient Parameter') HELP.GenericHelp(CONST.Version)
multi_jobs = [] sys.exit('Insufficient Parameter')
i = 0 multi_jobs = []
for device_id in self.UEDevices: i = 0
p = Process(target = self.InitializeUE_common, args = (device_id,i,COTS_UE,)) for device_id in self.UEDevices:
p.daemon = True p = Process(target = self.InitializeUE_common, args = (device_id,i,COTS_UE,))
p.start() p.daemon = True
multi_jobs.append(p) p.start()
i += 1 multi_jobs.append(p)
for job in multi_jobs: i += 1
job.join() for job in multi_jobs:
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) job.join()
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
else: #if an ID is specified, it is a module from the yaml infrastructure file
#RH
Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
Module_UE.ue_trace=ue_trace
is_module=Module_UE.CheckCMProcess()
if is_module:
Module_UE.EnableTrace()
time.sleep(5)
Module_UE.Command("wup")
logging.debug("Waiting for IP address to be assigned")
time.sleep(20)
logging.debug("Retrieve IP address")
status=Module_UE.GetModuleIPAddress()
if status==0:
HTML.CreateHtmlTestRow(Module_UE.UEIPAddress, 'OK', CONST.ALL_PROCESSES_OK)
logging.debug('UE IP addresss : '+ Module_UE.UEIPAddress)
else: #status==-1 failed to retrieve IP address
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
return
def InitializeOAIUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
def InitializeOAIUE(self,HTML,RAN,EPC,COTS_UE):
if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
HELP.GenericHelp(CONST.Version) HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter') sys.exit('Insufficient Parameter')
if self.air_interface == 'lte-uesoftmodem': if self.air_interface == 'lte-uesoftmodem':
result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args))
if result is None: if result is None:
@@ -403,13 +428,13 @@ class OaiCiTest():
SSH = sshconnection.SSHConnection() SSH = sshconnection.SSHConnection()
SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
# b2xx_fx3_utils reset procedure # b2xx_fx3_utils reset procedure
SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60) SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 90)
result = re.search('type: b200', SSH.getBefore()) result = re.search('type: b200', SSH.getBefore())
if result is not None: if result is not None:
logging.debug('Found a B2xx device --> resetting it') logging.debug('Found a B2xx device --> resetting it')
SSH.command('echo ' + self.UEPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) SSH.command('echo ' + self.UEPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10)
# Reloading FGPA bin firmware # Reloading FGPA bin firmware
SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60) SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 90)
result = re.search('type: n3xx', str(SSH.getBefore())) result = re.search('type: n3xx', str(SSH.getBefore()))
if result is not None: if result is not None:
logging.debug('Found a N3xx device --> resetting it') logging.debug('Found a N3xx device --> resetting it')
@@ -563,7 +588,7 @@ class OaiCiTest():
SSH.command('ifconfig oaitun_ue1', '\$', 4) SSH.command('ifconfig oaitun_ue1', '\$', 4)
SSH.command('ifconfig oaitun_ue1', '\$', 4) SSH.command('ifconfig oaitun_ue1', '\$', 4)
# ifconfig output is different between ubuntu 16 and ubuntu 18 # ifconfig output is different between ubuntu 16 and ubuntu 18
result = re.search('inet addr:1|inet 1', SSH.getBefore()) result = re.search('inet addr:[0-9]|inet [0-9]', SSH.getBefore())
if result is not None: if result is not None:
logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m') logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m')
tunnelInterfaceStatus = True tunnelInterfaceStatus = True
@@ -605,7 +630,7 @@ class OaiCiTest():
HTML.htmlUEFailureMsg='nr-uesoftmodem did NOT synced' HTML.htmlUEFailureMsg='nr-uesoftmodem did NOT synced'
HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE') HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE')
logging.error('\033[91mInitialize OAI UE Failed! \033[0m') logging.error('\033[91mInitialize OAI UE Failed! \033[0m')
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
def checkDevTTYisUnlocked(self): def checkDevTTYisUnlocked(self):
SSH = sshconnection.SSHConnection() SSH = sshconnection.SSHConnection()
@@ -683,7 +708,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
self.checkDevTTYisUnlocked() self.checkDevTTYisUnlocked()
def AttachCatM(self,HTML,RAN,COTS_UE,EPC): def AttachCatM(self,HTML,RAN,COTS_UE,EPC,InfraUE):
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
HELP.GenericHelp(CONST.Version) HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter') sys.exit('Insufficient Parameter')
@@ -756,9 +781,9 @@ class OaiCiTest():
html_cell = '<pre style="background-color:white">CAT-M module Attachment Failed</pre>' html_cell = '<pre style="background-color:white">CAT-M module Attachment Failed</pre>'
html_queue.put(html_cell) html_queue.put(html_cell)
HTML.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) HTML.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
def PingCatM(self,HTML,RAN,EPC,COTS_UE): def PingCatM(self,HTML,RAN,EPC,COTS_UE,InfraUE):
if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '':
HELP.GenericHelp(CONST.Version) HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter') sys.exit('Insufficient Parameter')
@@ -767,7 +792,7 @@ class OaiCiTest():
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
if (pStatus < 0): if (pStatus < 0):
HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
return return
try: try:
statusQueue = SimpleQueue() statusQueue = SimpleQueue()
@@ -788,7 +813,7 @@ class OaiCiTest():
moduleIPAddr = result.group('ipaddr') moduleIPAddr = result.group('ipaddr')
else: else:
HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
return return
ping_time = re.findall("-c (\d+)",str(self.ping_args)) ping_time = re.findall("-c (\d+)",str(self.ping_args))
device_id = 'catm' device_id = 'catm'
@@ -852,7 +877,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue) HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue)
else: else:
HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue) HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
except: except:
os.kill(os.getppid(),signal.SIGUSR1) os.kill(os.getppid(),signal.SIGUSR1)
@@ -944,64 +969,82 @@ class OaiCiTest():
except: except:
os.kill(os.getppid(),signal.SIGUSR1) os.kill(os.getppid(),signal.SIGUSR1)
def AttachUE(self,HTML,RAN,EPC,COTS_UE): def AttachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB
HELP.GenericHelp(CONST.Version) if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
sys.exit('Insufficient Parameter') HELP.GenericHelp(CONST.Version)
check_eNB = True sys.exit('Insufficient Parameter')
check_OAI_UE = False check_eNB = True
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) check_OAI_UE = False
if (pStatus < 0): pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) if (pStatus < 0):
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) HTML.CreateHtmlTestRow('N/A', 'KO', pStatus)
return self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
multi_jobs = [] return
status_queue = SimpleQueue() multi_jobs = []
lock = Lock() status_queue = SimpleQueue()
nb_ue_to_connect = 0 lock = Lock()
for device_id in self.UEDevices: nb_ue_to_connect = 0
if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach): for device_id in self.UEDevices:
self.UEDevicesStatus[nb_ue_to_connect] = CONST.UE_STATUS_ATTACHING if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach):
p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,nb_ue_to_connect,COTS_UE,)) self.UEDevicesStatus[nb_ue_to_connect] = CONST.UE_STATUS_ATTACHING
p.daemon = True p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,nb_ue_to_connect,COTS_UE,))
p.start() p.daemon = True
multi_jobs.append(p) p.start()
nb_ue_to_connect = nb_ue_to_connect + 1 multi_jobs.append(p)
for job in multi_jobs: nb_ue_to_connect = nb_ue_to_connect + 1
job.join() for job in multi_jobs:
job.join()
if (status_queue.empty()): if (status_queue.empty()):
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK) HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
return return
else:
attach_status = True
html_queue = SimpleQueue()
while (not status_queue.empty()):
count = status_queue.get()
if (count < 0):
attach_status = False
device_id = status_queue.get()
message = status_queue.get()
if (count < 0):
html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + '</pre>'
else:
html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + ' in ' + str(count + 2) + ' seconds</pre>'
html_queue.put(html_cell)
if (attach_status):
cnt = 0
while cnt < len(self.UEDevices):
if self.UEDevicesStatus[cnt] == CONST.UE_STATUS_ATTACHING:
self.UEDevicesStatus[cnt] = CONST.UE_STATUS_ATTACHED
cnt += 1
HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
result = re.search('T_stdout', str(RAN.Initialize_eNB_args))
if result is not None:
logging.debug('Waiting 5 seconds to fill up record file')
time.sleep(5)
else: else:
HTML.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) attach_status = True
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) html_queue = SimpleQueue()
while (not status_queue.empty()):
count = status_queue.get()
if (count < 0):
attach_status = False
device_id = status_queue.get()
message = status_queue.get()
if (count < 0):
html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + '</pre>'
else:
html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + ' in ' + str(count + 2) + ' seconds</pre>'
html_queue.put(html_cell)
if (attach_status):
cnt = 0
while cnt < len(self.UEDevices):
if self.UEDevicesStatus[cnt] == CONST.UE_STATUS_ATTACHING:
self.UEDevicesStatus[cnt] = CONST.UE_STATUS_ATTACHED
cnt += 1
HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
result = re.search('T_stdout', str(RAN.Initialize_eNB_args))
if result is not None:
logging.debug('Waiting 5 seconds to fill up record file')
time.sleep(5)
else:
HTML.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
else: #if an ID is specified, it is a module from the yaml infrastructure file
#Attention, as opposed to InitializeUE, the connect manager process is not checked as it is supposed to be active already
#only 1- module wakeup, 2- check IP address
Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
Module_UE.Command("wup")
logging.debug("Waiting for IP address to be assigned")
time.sleep(20)
logging.debug("Retrieve IP address")
status=Module_UE.GetModuleIPAddress()
if status==0:
HTML.CreateHtmlTestRow(Module_UE.UEIPAddress, 'OK', CONST.ALL_PROCESSES_OK)
logging.debug('UE IP addresss : '+ Module_UE.UEIPAddress)
else: #status==-1 failed to retrieve IP address
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
return
def DetachUE_common(self, device_id, idx,COTS_UE): def DetachUE_common(self, device_id, idx,COTS_UE):
try: try:
@@ -1025,37 +1068,44 @@ class OaiCiTest():
except: except:
os.kill(os.getppid(),signal.SIGUSR1) os.kill(os.getppid(),signal.SIGUSR1)
def DetachUE(self,HTML,RAN,EPC,COTS_UE): def DetachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB
HELP.GenericHelp(CONST.Version) if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
sys.exit('Insufficient Parameter') HELP.GenericHelp(CONST.Version)
check_eNB = True sys.exit('Insufficient Parameter')
check_OAI_UE = False check_eNB = True
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) check_OAI_UE = False
if (pStatus < 0): pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) if (pStatus < 0):
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) HTML.CreateHtmlTestRow('N/A', 'KO', pStatus)
return self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
multi_jobs = [] return
cnt = 0 multi_jobs = []
for device_id in self.UEDevices: cnt = 0
self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHING for device_id in self.UEDevices:
p = Process(target = self.DetachUE_common, args = (device_id,cnt,COTS_UE,)) self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHING
p.daemon = True p = Process(target = self.DetachUE_common, args = (device_id,cnt,COTS_UE,))
p.start() p.daemon = True
multi_jobs.append(p) p.start()
cnt += 1 multi_jobs.append(p)
for job in multi_jobs: cnt += 1
job.join() for job in multi_jobs:
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) job.join()
result = re.search('T_stdout', str(RAN.Initialize_eNB_args)) HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
if result is not None: result = re.search('T_stdout', str(RAN.Initialize_eNB_args))
logging.debug('Waiting 5 seconds to fill up record file') if result is not None:
time.sleep(5) logging.debug('Waiting 5 seconds to fill up record file')
cnt = 0 time.sleep(5)
while cnt < len(self.UEDevices): cnt = 0
self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHED while cnt < len(self.UEDevices):
cnt += 1 self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHED
cnt += 1
else:#if an ID is specified, it is a module from the yaml infrastructure file
Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
Module_UE.Command("detach")
HTML.CreateHtmlTestRow('NA', 'OK', CONST.ALL_PROCESSES_OK)
def RebootUE_common(self, device_id): def RebootUE_common(self, device_id):
try: try:
@@ -1303,7 +1353,7 @@ class OaiCiTest():
except: except:
os.kill(os.getppid(),signal.SIGUSR1) os.kill(os.getppid(),signal.SIGUSR1)
def CheckStatusUE(self,HTML,RAN,EPC,COTS_UE): def CheckStatusUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
HELP.GenericHelp(CONST.Version) HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter') sys.exit('Insufficient Parameter')
@@ -1350,7 +1400,7 @@ class OaiCiTest():
if (status_queue.empty()): if (status_queue.empty()):
HTML.CreateHtmlTestRow(htmlOptions, 'KO', CONST.ALL_PROCESSES_OK) HTML.CreateHtmlTestRow(htmlOptions, 'KO', CONST.ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
else: else:
check_status = True check_status = True
html_queue = SimpleQueue() html_queue = SimpleQueue()
@@ -1366,7 +1416,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue) HTML.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue)
else: else:
HTML.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue) HTML.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
def GetAllUEIPAddresses(self): def GetAllUEIPAddresses(self):
SSH = sshconnection.SSHConnection() SSH = sshconnection.SSHConnection()
@@ -1437,14 +1487,20 @@ class OaiCiTest():
statusQueue.put(message) statusQueue.put(message)
lock.release() lock.release()
def Ping_common(self, lock, UE_IPAddress, device_id, statusQueue,EPC): def Ping_common(self, lock, UE_IPAddress, device_id, statusQueue,EPC, Module_UE):
try: try:
SSH = sshconnection.SSHConnection() SSH = sshconnection.SSHConnection()
# Launch ping on the EPC side (true for ltebox and old open-air-cn) # Launch ping on the EPC side (true for ltebox and old open-air-cn)
# But for OAI-Rel14-CUPS, we launch from python executor # But for OAI-Rel14-CUPS, we launch from python executor
launchFromEpc = True launchFromEpc = True
launchFromModule = False
if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE): if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE):
launchFromEpc = False launchFromEpc = False
#if module, ping from module to EPC
if self.ue_id!='':
launchFromEpc = False
launchfromModule = True
ping_time = re.findall("-c (\d+)",str(self.ping_args)) ping_time = re.findall("-c (\d+)",str(self.ping_args))
if launchFromEpc: if launchFromEpc:
@@ -1462,21 +1518,34 @@ class OaiCiTest():
#copy the ping log file to have it locally for analysis (ping stats) #copy the ping log file to have it locally for analysis (ping stats)
SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '.') SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '.')
else: else:
#ping log file is on the python executor if launchfromModule == False:
cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' #ping log file is on the python executor
message = cmd + '\n' cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log'
logging.debug(cmd) message = cmd + '\n'
ret = subprocess.run(cmd, shell=True) logging.debug(cmd)
ping_status = ret.returncode ret = subprocess.run(cmd, shell=True)
#copy the ping log file to an other folder for log collection (source and destination are EPC) ping_status = ret.returncode
SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') #copy the ping log file to an other folder for log collection (source and destination are EPC)
#copy the ping log file to have it locally for analysis (ping stats) SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
logging.debug(EPC.SourceCodePath + 'ping_' + self.testCase_id + '_' + device_id + '.log') #copy the ping log file to have it locally for analysis (ping stats)
SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath +'/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '.') logging.debug(EPC.SourceCodePath + 'ping_' + self.testCase_id + '_' + device_id + '.log')
SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath +'/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '.')
SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
#cat is executed on EPC
SSH.command('cat ' + EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
else: #launch from Module
SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
#ping from module NIC rather than IP address to make sure round trip is over the air
cmd = 'ping -I ' + Module_UE.UENetwork + ' ' + self.ping_args + ' ' + EPC.IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',int(ping_time[0])*1.5)
#copy the ping log file to have it locally for analysis (ping stats)
SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'ping_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
#cat is executed locally
SSH.command('cat ping_' + self.testCase_id + '_' + self.ue_id + '.log', '\$', 5)
ping_status=0
SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
#cat is executed on EPC
SSH.command('cat ' + EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
# TIMEOUT CASE # TIMEOUT CASE
if ping_status < 0: if ping_status < 0:
message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!' message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!'
@@ -1567,14 +1636,14 @@ class OaiCiTest():
html_queue.put(html_cell) html_queue.put(html_cell)
HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
def PingNoS1(self,HTML,RAN,EPC,COTS_UE): def PingNoS1(self,HTML,RAN,EPC,COTS_UE,InfraUE):
SSH=sshconnection.SSHConnection() SSH=sshconnection.SSHConnection()
check_eNB = True check_eNB = True
check_OAI_UE = True check_OAI_UE = True
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
if (pStatus < 0): if (pStatus < 0):
HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
return return
ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args)) ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args))
if ping_from_eNB is not None: if ping_from_eNB is not None:
@@ -1660,10 +1729,10 @@ class OaiCiTest():
except: except:
os.kill(os.getppid(),signal.SIGUSR1) os.kill(os.getppid(),signal.SIGUSR1)
def Ping(self,HTML,RAN,EPC,COTS_UE): def Ping(self,HTML,RAN,EPC,COTS_UE, InfraUE):
result = re.search('noS1', str(RAN.Initialize_eNB_args)) result = re.search('noS1', str(RAN.Initialize_eNB_args))
if result is not None: if result is not None:
self.PingNoS1(HTML,RAN,EPC,COTS_UE) self.PingNoS1(HTML,RAN,EPC,COTS_UE,InfraUE)
return return
if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '':
HELP.GenericHelp(CONST.Version) HELP.GenericHelp(CONST.Version)
@@ -1676,20 +1745,32 @@ class OaiCiTest():
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
if (pStatus < 0): if (pStatus < 0):
HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
return
ueIpStatus = self.GetAllUEIPAddresses()
if (ueIpStatus < 0):
HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
return return
if self.ue_id=="":
Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra['dummy']) #RH, temporary, we need a dummy Module_UE object to pass to Ping_common
ueIpStatus = self.GetAllUEIPAddresses()
if (ueIpStatus < 0):
HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
return
else:
self.UEIPAddresses=[]
Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
Module_UE.GetModuleIPAddress()
self.UEIPAddresses.append(Module_UE.UEIPAddress)
logging.debug(self.UEIPAddresses)
multi_jobs = [] multi_jobs = []
i = 0 i = 0
lock = Lock() lock = Lock()
status_queue = SimpleQueue() status_queue = SimpleQueue()
for UE_IPAddress in self.UEIPAddresses: for UE_IPAddress in self.UEIPAddresses:
device_id = self.UEDevices[i] if self.ue_id=="":
p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,EPC,)) device_id = self.UEDevices[i]
else:
device_id = Module_UE.ID + "-" + Module_UE.Kind
p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,EPC,Module_UE,))
p.daemon = True p.daemon = True
p.start() p.start()
multi_jobs.append(p) multi_jobs.append(p)
@@ -1699,7 +1780,7 @@ class OaiCiTest():
if (status_queue.empty()): if (status_queue.empty()):
HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.ALL_PROCESSES_OK) HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
else: else:
ping_status = True ping_status = True
html_queue = SimpleQueue() html_queue = SimpleQueue()
@@ -1716,7 +1797,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue)
else: else:
HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
def Iperf_ComputeTime(self): def Iperf_ComputeTime(self):
result = re.search('-t (?P<iperf_time>\d+)', str(self.iperf_args)) result = re.search('-t (?P<iperf_time>\d+)', str(self.iperf_args))
@@ -1864,8 +1945,8 @@ class OaiCiTest():
else: else:
return -2 return -2
def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options, filename,type):
if (not os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): if (not os.path.isfile(filename)):
self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log')
return return
# Computing the requested bandwidth in float # Computing the requested bandwidth in float
@@ -1890,14 +1971,18 @@ class OaiCiTest():
req_bandwidth = '%.1f Gbits/sec' % req_bw req_bandwidth = '%.1f Gbits/sec' % req_bw
req_bw = req_bw * 1000000000 req_bw = req_bw * 1000000000
server_file = open('iperf_server_' + self.testCase_id + '_' + device_id + '.log', 'r') server_file = open(filename, 'r')
br_sum = 0.0 br_sum = 0.0
ji_sum = 0.0 ji_sum = 0.0
pl_sum = 0 pl_sum = 0
ps_sum = 0 ps_sum = 0
row_idx = 0 row_idx = 0
for line in server_file.readlines(): for line in server_file.readlines():
result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(?P<lostPack>[0-9]+)/ +(?P<sentPack>[0-9]+)', str(line)) if type==0:
result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(?P<lostPack>[0-9]+)/ +(?P<sentPack>[0-9]+)', str(line))
else:
result = re.search('^\[ \d\].+ +(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(?P<lostPack>[0-9]+)\/(?P<sentPack>[0-9]+)', str(line))
if result is not None: if result is not None:
bitrate = result.group('bitrate') bitrate = result.group('bitrate')
jitter = result.group('jitter') jitter = result.group('jitter')
@@ -2127,12 +2212,72 @@ class OaiCiTest():
SSH.command('docker cp prod-trf-gen:/iperf-2.0.5/iperf_server_' + self.testCase_id + '_' + device_id + '.log ' + EPC.SourceCodePath + '/scripts', '\$', 5) SSH.command('docker cp prod-trf-gen:/iperf-2.0.5/iperf_server_' + self.testCase_id + '_' + device_id + '.log ' + EPC.SourceCodePath + '/scripts', '\$', 5)
SSH.close() SSH.close()
SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath+ '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath+ '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) filename='iperf_server_' + self.testCase_id + '_' + device_id + '.log'
self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options,filename,0)
# in case of OAI-UE # in case of OAI-UE
if (device_id == 'OAI-UE'): if (device_id == 'OAI-UE'):
SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.') SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.')
SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
def Iperf_Module(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC, Module_UE):
SSH = sshconnection.SSHConnection()
iperf_time = self.Iperf_ComputeTime()
if self.iperf_direction=="DL":
logging.debug("Iperf for Module in DL mode detected")
#server side UE
SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
cmd = 'rm iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',5)
cmd = 'echo $USER; nohup /opt/iperf-2.0.10/iperf -s -B ' + UE_IPAddress + ' -u 2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',5)
#client side EPC
SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
cmd = 'rm iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',5)
cmd = 'iperf -c ' + UE_IPAddress + ' ' + self.iperf_args + ' 2>&1 > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',int(iperf_time)*5.0)
#copy the 2 resulting files locally
SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
#send for analysis
filename='iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, self.iperf_args,filename,1)
elif self.iperf_direction=="UL":#does not work at the moment
logging.debug("Iperf for Module in UL mode detected")
#server side EPC
SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
cmd = 'rm iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',5)
cmd = 'echo $USER; nohup iperf -s -u 2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',5)
#client side UE
SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
cmd = 'rm iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',5)
SSH.command('/opt/iperf-2.0.10/iperf -c 192.172.0.1 ' + self.iperf_args + ' 2>&1 > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '\$', int(iperf_time)*5.0)
#copy the 2 resulting files locally
SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
#send for analysis
filename='iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, self.iperf_args,filename,1)
else :
logging.debug("Incorrect or missing IPERF direction in XML")
SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
cmd = 'killall --signal=SIGKILL iperf'
SSH.command(cmd,'\$',5)
SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
cmd = 'killall --signal=SIGKILL iperf'
SSH.command(cmd,'\$',5)
SSH.close()
return
def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC): def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC):
try: try:
SSH = sshconnection.SSHConnection() SSH = sshconnection.SSHConnection()
@@ -2229,8 +2374,13 @@ class OaiCiTest():
# Launch the IPERF client on the EPC side for DL (true for ltebox and old open-air-cn # Launch the IPERF client on the EPC side for DL (true for ltebox and old open-air-cn
# But for OAI-Rel14-CUPS, we launch from python executor # But for OAI-Rel14-CUPS, we launch from python executor
launchFromEpc = True launchFromEpc = True
launchFromModule = False
if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE): if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE):
launchFromEpc = False launchFromEpc = False
#if module
if self.ue_id!='' and self.iperf :
launchFromEpc = False
launchfromModule = True
# When using a docker-based deployment, IPERF client shall be launched from trf container # When using a docker-based deployment, IPERF client shall be launched from trf container
launchFromTrfContainer = False launchFromTrfContainer = False
if re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE): if re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE):
@@ -2334,7 +2484,8 @@ class OaiCiTest():
subprocess.run(cmd, shell=True) subprocess.run(cmd, shell=True)
except: except:
pass pass
self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) filename='iperf_server_' + self.testCase_id + '_' + device_id + '.log'
self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options,filename,0)
# in case of OAI UE: # in case of OAI UE:
if (device_id == 'OAI-UE'): if (device_id == 'OAI-UE'):
@@ -2347,7 +2498,7 @@ class OaiCiTest():
except: except:
os.kill(os.getppid(),signal.SIGUSR1) os.kill(os.getppid(),signal.SIGUSR1)
def IperfNoS1(self,HTML,RAN,EPC,COTS_UE): def IperfNoS1(self,HTML,RAN,EPC,COTS_UE,InfraUE):
SSH = sshconnection.SSHConnection() SSH = sshconnection.SSHConnection()
if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '':
HELP.GenericHelp(CONST.Version) HELP.GenericHelp(CONST.Version)
@@ -2357,7 +2508,7 @@ class OaiCiTest():
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
if (pStatus < 0): if (pStatus < 0):
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
return return
server_on_enb = re.search('-R', str(self.iperf_args)) server_on_enb = re.search('-R', str(self.iperf_args))
if server_on_enb is not None: if server_on_enb is not None:
@@ -2422,7 +2573,8 @@ class OaiCiTest():
if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')): if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')):
os.remove('iperf_server_' + self.testCase_id + '.log') os.remove('iperf_server_' + self.testCase_id + '.log')
SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log')
self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) filename='iperf_server_' + self.testCase_id + '_OAI-UE.log'
self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options,filename,0)
# copying on the EPC server for logCollection # copying on the EPC server for logCollection
if (clientStatus == -1): if (clientStatus == -1):
@@ -2455,12 +2607,12 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue)
else: else:
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
def Iperf(self,HTML,RAN,EPC,COTS_UE): def Iperf(self,HTML,RAN,EPC,COTS_UE, InfraUE):
result = re.search('noS1', str(RAN.Initialize_eNB_args)) result = re.search('noS1', str(RAN.Initialize_eNB_args))
if result is not None: if result is not None:
self.IperfNoS1(HTML,RAN,EPC,COTS_UE) self.IperfNoS1(HTML,RAN,EPC,COTS_UE,InfraUE)
return return
if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
HELP.GenericHelp(CONST.Version) HELP.GenericHelp(CONST.Version)
@@ -2473,15 +2625,24 @@ class OaiCiTest():
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
if (pStatus < 0): if (pStatus < 0):
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
return
ueIpStatus = self.GetAllUEIPAddresses()
if (ueIpStatus < 0):
logging.debug('going here')
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
return return
if self.ue_id=="":#is not a module, follow legacy code
ueIpStatus = self.GetAllUEIPAddresses()
if (ueIpStatus < 0):
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
return
else: #is a module
self.UEIPAddresses=[]
Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
Module_UE.GetModuleIPAddress()
self.UEIPAddresses.append(Module_UE.UEIPAddress)
self.dummyIperfVersion = '2.0.10' self.dummyIperfVersion = '2.0.10'
#cmd = 'iperf --version' #cmd = 'iperf --version'
#logging.debug(cmd + '\n') #logging.debug(cmd + '\n')
@@ -2498,9 +2659,15 @@ class OaiCiTest():
ue_num = len(self.UEIPAddresses) ue_num = len(self.UEIPAddresses)
lock = Lock() lock = Lock()
status_queue = SimpleQueue() status_queue = SimpleQueue()
logging.debug(self.UEIPAddresses)
for UE_IPAddress in self.UEIPAddresses: for UE_IPAddress in self.UEIPAddresses:
device_id = self.UEDevices[i] device_id = self.UEDevices[i]
p = Process(target = self.Iperf_common, args = (lock,UE_IPAddress,device_id,i,ue_num,status_queue,EPC,)) #special quick and dirty treatment for modules, iperf to be restructured
if self.ue_id!="": #is module
device_id = Module_UE.ID + "-" + Module_UE.Kind
p = Process(target = self.Iperf_Module ,args = (lock, UE_IPAddress, device_id, i, ue_num, status_queue, EPC, Module_UE,))
else: #legacy code
p = Process(target = self.Iperf_common, args = (lock, UE_IPAddress, device_id, i, ue_num, status_queue, EPC, ))
p.daemon = True p.daemon = True
p.start() p.start()
multi_jobs.append(p) multi_jobs.append(p)
@@ -2510,7 +2677,7 @@ class OaiCiTest():
if (status_queue.empty()): if (status_queue.empty()):
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.ALL_PROCESSES_OK) HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfaUE)
else: else:
iperf_status = True iperf_status = True
iperf_noperf = False iperf_noperf = False
@@ -2532,7 +2699,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue)
else: else:
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
def CheckProcessExist(self, check_eNB, check_OAI_UE,RAN,EPC): def CheckProcessExist(self, check_eNB, check_OAI_UE,RAN,EPC):
multi_jobs = [] multi_jobs = []
@@ -2937,22 +3104,34 @@ class OaiCiTest():
except: except:
os.kill(os.getppid(),signal.SIGUSR1) os.kill(os.getppid(),signal.SIGUSR1)
def TerminateUE(self,HTML,COTS_UE): def TerminateUE(self,HTML,COTS_UE,InfraUE,ue_trace):
terminate_ue_flag = False if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB
self.GetAllUEDevices(terminate_ue_flag) terminate_ue_flag = False
multi_jobs = [] self.GetAllUEDevices(terminate_ue_flag)
i = 0 multi_jobs = []
for device_id in self.UEDevices: i = 0
p = Process(target= self.TerminateUE_common, args = (device_id,i,COTS_UE,)) for device_id in self.UEDevices:
p.daemon = True p = Process(target= self.TerminateUE_common, args = (device_id,i,COTS_UE,))
p.start() p.daemon = True
multi_jobs.append(p) p.start()
i += 1 multi_jobs.append(p)
for job in multi_jobs: i += 1
job.join() for job in multi_jobs:
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) job.join()
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
else: #if an ID is specified, it is a module from the yaml infrastructure file
Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
Module_UE.ue_trace=ue_trace
Module_UE.Command("detach")
Module_UE.DisableTrace()
Module_UE.DisableCM()
archive_destination=Module_UE.LogCollect()
if Module_UE.ue_trace=='yes':
HTML.CreateHtmlTestRow('QLog at : '+archive_destination, 'OK', CONST.ALL_PROCESSES_OK)
else:
HTML.CreateHtmlTestRow('QLog trace is disabled', 'OK', CONST.ALL_PROCESSES_OK)
def TerminateOAIUE(self,HTML,RAN,COTS_UE,EPC): def TerminateOAIUE(self,HTML,RAN,COTS_UE,EPC, InfraUE):
SSH = sshconnection.SSHConnection() SSH = sshconnection.SSHConnection()
SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5)
@@ -2993,11 +3172,11 @@ class OaiCiTest():
# Not an error then # Not an error then
if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'):
self.Initialize_OAI_UE_args = '' self.Initialize_OAI_UE_args = ''
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
else: else:
if (logStatus == CONST.OAI_UE_PROCESS_COULD_NOT_SYNC): if (logStatus == CONST.OAI_UE_PROCESS_COULD_NOT_SYNC):
self.Initialize_OAI_UE_args = '' self.Initialize_OAI_UE_args = ''
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
else: else:
logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m') logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m')
HTML.htmlUEFailureMsg='<b>' + ueAction + ' Completed</b>\n' + HTML.htmlUEFailureMsg HTML.htmlUEFailureMsg='<b>' + ueAction + ' Completed</b>\n' + HTML.htmlUEFailureMsg
@@ -3006,21 +3185,21 @@ class OaiCiTest():
else: else:
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
def AutoTerminateUEandeNB(self,HTML,RAN,COTS_UE,EPC): def AutoTerminateUEandeNB(self,HTML,RAN,COTS_UE,EPC,InfraUE):
if (self.ADBIPAddress != 'none'): if (self.ADBIPAddress != 'none'):
self.testCase_id = 'AUTO-KILL-UE' self.testCase_id = 'AUTO-KILL-UE'
HTML.testCase_id=self.testCase_id HTML.testCase_id=self.testCase_id
self.desc = 'Automatic Termination of UE' self.desc = 'Automatic Termination of UE'
HTML.desc='Automatic Termination of UE' HTML.desc='Automatic Termination of UE'
self.ShowTestID() self.ShowTestID()
self.TerminateUE(HTML,COTS_UE) self.TerminateUE(HTML,COTS_UE,InfraUE,self.ue_trace)
if (self.Initialize_OAI_UE_args != ''): if (self.Initialize_OAI_UE_args != ''):
self.testCase_id = 'AUTO-KILL-OAI-UE' self.testCase_id = 'AUTO-KILL-OAI-UE'
HTML.testCase_id=self.testCase_id HTML.testCase_id=self.testCase_id
self.desc = 'Automatic Termination of OAI-UE' self.desc = 'Automatic Termination of OAI-UE'
HTML.desc='Automatic Termination of OAI-UE' HTML.desc='Automatic Termination of OAI-UE'
self.ShowTestID() self.ShowTestID()
self.TerminateOAIUE(HTML,RAN,COTS_UE,EPC) self.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE)
if (RAN.Initialize_eNB_args != ''): if (RAN.Initialize_eNB_args != ''):
self.testCase_id = 'AUTO-KILL-RAN' self.testCase_id = 'AUTO-KILL-RAN'
HTML.testCase_id=self.testCase_id HTML.testCase_id=self.testCase_id
@@ -3273,7 +3452,7 @@ class OaiCiTest():
UhdVersion = result.group('uhd_version') UhdVersion = result.group('uhd_version')
logging.debug('UHD Version is: ' + UhdVersion) logging.debug('UHD Version is: ' + UhdVersion)
HTML.UhdVersion[idx]=UhdVersion HTML.UhdVersion[idx]=UhdVersion
SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 60) SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 90)
usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', SSH.getBefore()) usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', SSH.getBefore())
count = 0 count = 0
for board in usrp_boards: for board in usrp_boards:
+191 -191
View File
@@ -1,191 +1,191 @@
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more # * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# * contributor license agreements. See the NOTICE file distributed with # * contributor license agreements. See the NOTICE file distributed with
# * this work for additional information regarding copyright ownership. # * this work for additional information regarding copyright ownership.
# * The OpenAirInterface Software Alliance licenses this file to You under # * 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 # * the OAI Public License, Version 1.1 (the "License"); you may not use this file
# * except in compliance with the License. # * except in compliance with the License.
# * You may obtain a copy of the License at # * You may obtain a copy of the License at
# * # *
# * http://www.openairinterface.org/?page_id=698 # * http://www.openairinterface.org/?page_id=698
# * # *
# * Unless required by applicable law or agreed to in writing, software # * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS, # * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and # * See the License for the specific language governing permissions and
# * limitations under the License. # * limitations under the License.
# *------------------------------------------------------------------------------- # *-------------------------------------------------------------------------------
# * For more information about the OpenAirInterface (OAI) Software Alliance: # * For more information about the OpenAirInterface (OAI) Software Alliance:
# * contact@openairinterface.org # * contact@openairinterface.org
# */ # */
#--------------------------------------------------------------------- #---------------------------------------------------------------------
# Python for CI of OAI-eNB + COTS-UE # Python for CI of OAI-eNB + COTS-UE
# #
# Required Python Version # Required Python Version
# Python 3.x # Python 3.x
# #
# Required Python Package # Required Python Package
# pexpect # pexpect
#--------------------------------------------------------------------- #---------------------------------------------------------------------
#to use logging.info() #to use logging.info()
import logging import logging
#to create a SSH object locally in the methods #to create a SSH object locally in the methods
import sshconnection import sshconnection
#to update the HTML object #to update the HTML object
import html import html
from multiprocessing import SimpleQueue from multiprocessing import SimpleQueue
#for log folder maintenance #for log folder maintenance
import os import os
class PhySim: class PhySim:
def __init__(self): def __init__(self):
self.buildargs = "" self.buildargs = ""
self.runargs = "" self.runargs = ""
self.eNBIpAddr = "" self.eNBIpAddr = ""
self.eNBUserName = "" self.eNBUserName = ""
self.eNBPassWord = "" self.eNBPassWord = ""
self.eNBSourceCodePath = "" self.eNBSourceCodePath = ""
self.ranRepository = "" self.ranRepository = ""
self.ranBranch = "" self.ranBranch = ""
self.ranCommitID= "" self.ranCommitID= ""
self.ranAllowMerge= "" self.ranAllowMerge= ""
self.ranTargetBranch= "" self.ranTargetBranch= ""
self.exitStatus=0 self.exitStatus=0
self.forced_workspace_cleanup=False self.forced_workspace_cleanup=False
#private attributes #private attributes
self.__workSpacePath='' self.__workSpacePath=''
self.__buildLogFile='compile_phy_sim.log' self.__buildLogFile='compile_phy_sim.log'
self.__runLogFile='' self.__runLogFile=''
self.__runResults=[] self.__runResults=[]
self.__runLogPath='phy_sim_logs' self.__runLogPath='phy_sim_logs'
#----------------- #-----------------
#PRIVATE Methods #PRIVATE Methods
#----------------- #-----------------
def __CheckResults_PhySim(self,HTML,CONST,testcase_id): def __CheckResults_PhySim(self,HTML,CONST,testcase_id):
mySSH = sshconnection.SSHConnection() mySSH = sshconnection.SSHConnection()
mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord) mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
#retrieve run log file and store it locally$ #retrieve run log file and store it locally$
mySSH.copyin(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord, self.__workSpacePath+self.__runLogFile, '.') mySSH.copyin(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord, self.__workSpacePath+self.__runLogFile, '.')
mySSH.close() mySSH.close()
#parse results looking for Encoding and Decoding mean values #parse results looking for Encoding and Decoding mean values
self.__runResults=[] self.__runResults=[]
with open(self.__runLogFile) as f: with open(self.__runLogFile) as f:
for line in f: for line in f:
if 'mean' in line: if 'mean' in line:
self.__runResults.append(line) self.__runResults.append(line)
#the values are appended for each mean value (2), so we take these 2 values from the list #the values are appended for each mean value (2), so we take these 2 values from the list
info=self.__runResults[0]+self.__runResults[1] info=self.__runResults[0]+self.__runResults[1]
#once parsed move the local logfile to its folder for tidiness #once parsed move the local logfile to its folder for tidiness
os.system('mv '+self.__runLogFile+' '+ self.__runLogPath+'/.') os.system('mv '+self.__runLogFile+' '+ self.__runLogPath+'/.')
#updating the HTML with results #updating the HTML with results
html_cell = '<pre style="background-color:white">' + info + '</pre>' html_cell = '<pre style="background-color:white">' + info + '</pre>'
html_queue=SimpleQueue() html_queue=SimpleQueue()
html_queue.put(html_cell) html_queue.put(html_cell)
HTML.CreateHtmlTestRowQueue(self.runargs, 'OK', 1, html_queue) HTML.CreateHtmlTestRowQueue(self.runargs, 'OK', 1, html_queue)
return HTML return HTML
def __CheckBuild_PhySim(self, HTML, CONST): def __CheckBuild_PhySim(self, HTML, CONST):
self.__workSpacePath=self.eNBSourceCodePath+'/cmake_targets/' self.__workSpacePath=self.eNBSourceCodePath+'/cmake_targets/'
mySSH = sshconnection.SSHConnection() mySSH = sshconnection.SSHConnection()
mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord) mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
#retrieve compile log file and store it locally #retrieve compile log file and store it locally
mySSH.copyin(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord, self.__workSpacePath+self.__buildLogFile, '.') mySSH.copyin(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord, self.__workSpacePath+self.__buildLogFile, '.')
#delete older run log file #delete older run log file
mySSH.command('rm ' + self.__workSpacePath+self.__runLogFile, '\$', 5) mySSH.command('rm ' + self.__workSpacePath+self.__runLogFile, '\$', 5)
mySSH.close() mySSH.close()
#check build result from local compile log file #check build result from local compile log file
buildStatus=False buildStatus=False
with open(self.__buildLogFile) as f: with open(self.__buildLogFile) as f:
#nr_prachsim is the last compile step #nr_prachsim is the last compile step
if 'nr_prachsim compiled' in f.read(): if 'nr_prachsim compiled' in f.read():
buildStatus=True buildStatus=True
#update HTML based on build status #update HTML based on build status
if buildStatus: if buildStatus:
HTML.CreateHtmlTestRow(self.buildargs, 'OK', CONST.ALL_PROCESSES_OK, 'LDPC') HTML.CreateHtmlTestRow(self.buildargs, 'OK', CONST.ALL_PROCESSES_OK, 'LDPC')
self.exitStatus=0 self.exitStatus=0
else: else:
logging.error('\u001B[1m Building Physical Simulators Failed\u001B[0m') logging.error('\u001B[1m Building Physical Simulators Failed\u001B[0m')
HTML.CreateHtmlTestRow(self.buildargs, 'KO', CONST.ALL_PROCESSES_OK, 'LDPC') HTML.CreateHtmlTestRow(self.buildargs, 'KO', CONST.ALL_PROCESSES_OK, 'LDPC')
HTML.CreateHtmlTabFooter(False) HTML.CreateHtmlTabFooter(False)
#exitStatus=1 will do a sys.exit in main #exitStatus=1 will do a sys.exit in main
self.exitStatus=1 self.exitStatus=1
return HTML return HTML
#-----------------$ #-----------------$
#PUBLIC Methods$ #PUBLIC Methods$
#-----------------$ #-----------------$
def Build_PhySim(self,htmlObj,constObj): def Build_PhySim(self,htmlObj,constObj):
mySSH = sshconnection.SSHConnection() mySSH = sshconnection.SSHConnection()
mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord) mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
#create working dir #create working dir
mySSH.command('mkdir -p ' + self.eNBSourceCodePath, '\$', 5) mySSH.command('mkdir -p ' + self.eNBSourceCodePath, '\$', 5)
mySSH.command('cd ' + self.eNBSourceCodePath, '\$', 5) mySSH.command('cd ' + self.eNBSourceCodePath, '\$', 5)
if not self.ranRepository.lower().endswith('.git'): if not self.ranRepository.lower().endswith('.git'):
self.ranRepository+='.git' self.ranRepository+='.git'
#git clone #git clone
mySSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) mySSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600)
#git config #git config
mySSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) mySSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
mySSH.command('git config user.name "OAI Jenkins"', '\$', 5) mySSH.command('git config user.name "OAI Jenkins"', '\$', 5)
#git clean depending on self.forced_workspace_cleanup captured in xml #git clean depending on self.forced_workspace_cleanup captured in xml
if self.forced_workspace_cleanup==True: if self.forced_workspace_cleanup==True:
logging.info('Cleaning workspace ...') logging.info('Cleaning workspace ...')
mySSH.command('echo ' + self.eNBPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30) mySSH.command('echo ' + self.eNBPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30)
else: else:
logging.info('Workspace cleaning was disabled') logging.info('Workspace cleaning was disabled')
# if the commit ID is provided, use it to point to it # if the commit ID is provided, use it to point to it
if self.ranCommitID != '': if self.ranCommitID != '':
mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 5) mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
# if the branch is not develop, then it is a merge request and we need to do # if the branch is not develop, then it is a merge request and we need to do
# the potential merge. Note that merge conflicts should have already been checked earlier # the potential merge. Note that merge conflicts should have already been checked earlier
if (self.ranAllowMerge): if (self.ranAllowMerge):
if self.ranTargetBranch == '': if self.ranTargetBranch == '':
if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'): if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'):
mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5)
else: else:
logging.info('Merging with the target branch: ' + self.ranTargetBranch) logging.info('Merging with the target branch: ' + self.ranTargetBranch)
mySSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5) mySSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
#build #build
mySSH.command('source oaienv', '\$', 5) mySSH.command('source oaienv', '\$', 5)
mySSH.command('cd cmake_targets', '\$', 5) mySSH.command('cd cmake_targets', '\$', 5)
mySSH.command('mkdir -p log', '\$', 5) mySSH.command('mkdir -p log', '\$', 5)
mySSH.command('chmod 777 log', '\$', 5) mySSH.command('chmod 777 log', '\$', 5)
mySSH.command('stdbuf -o0 ./build_oai ' + self.buildargs + ' 2>&1 | stdbuf -o0 tee ' + self.__buildLogFile, 'Bypassing the Tests|build have failed', 1500) mySSH.command('stdbuf -o0 ./build_oai ' + self.buildargs + ' 2>&1 | stdbuf -o0 tee ' + self.__buildLogFile, 'Bypassing the Tests|build have failed', 1500)
mySSH.close() mySSH.close()
#check build status and update HTML object #check build status and update HTML object
lHTML = html.HTMLManagement() lHTML = html.HTMLManagement()
lHTML=self.__CheckBuild_PhySim(htmlObj,constObj) lHTML=self.__CheckBuild_PhySim(htmlObj,constObj)
return lHTML return lHTML
def Run_PhySim(self,htmlObj,constObj,testcase_id): def Run_PhySim(self,htmlObj,constObj,testcase_id):
#create run logs folder locally #create run logs folder locally
os.system('mkdir -p ./'+self.__runLogPath) os.system('mkdir -p ./'+self.__runLogPath)
#log file is tc_<testcase_id>.log remotely #log file is tc_<testcase_id>.log remotely
self.__runLogFile='physim_'+str(testcase_id)+'.log' self.__runLogFile='physim_'+str(testcase_id)+'.log'
#open a session for test run #open a session for test run
mySSH = sshconnection.SSHConnection() mySSH = sshconnection.SSHConnection()
mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord) mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
mySSH.command('cd '+self.__workSpacePath,'\$',5) mySSH.command('cd '+self.__workSpacePath,'\$',5)
#run and redirect the results to a log file #run and redirect the results to a log file
mySSH.command(self.__workSpacePath+'phy_simulators/build/ldpctest ' + self.runargs + ' >> '+self.__runLogFile, '\$', 30) mySSH.command(self.__workSpacePath+'phy_simulators/build/ldpctest ' + self.runargs + ' >> '+self.__runLogFile, '\$', 30)
mySSH.close() mySSH.close()
#return updated HTML to main #return updated HTML to main
lHTML = html.HTMLManagement() lHTML = html.HTMLManagement()
lHTML=self.__CheckResults_PhySim(htmlObj,constObj,testcase_id) lHTML=self.__CheckResults_PhySim(htmlObj,constObj,testcase_id)
return lHTML return lHTML
+337
View File
@@ -0,0 +1,337 @@
#/*
# * 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 logging
import sshconnection as SSH
import html
import os
import re
import time
import sys
import constants as CONST
import helpreadme as HELP
class PhySim:
def __init__(self):
self.eNBIpAddr = ""
self.eNBUserName = ""
self.eNBPassword = ""
self.OCUserName = ""
self.OCPassword = ""
self.OCProjectName = ""
self.eNBSourceCodePath = ""
self.ranRepository = ""
self.ranBranch = ""
self.ranCommitID= ""
self.ranAllowMerge= False
self.ranTargetBranch= ""
self.testResult = {}
self.testCount = [0,0,0]
self.testSummary = {}
self.testStatus = False
#-----------------$
#PUBLIC Methods$
#-----------------$
def Deploy_PhySim(self, HTML, RAN):
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
lPassWord = self.eNBPassword
lSourcePath = self.eNBSourceCodePath
ocUserName = self.OCUserName
ocPassword = self.OCPassword
ocProjectName = self.OCProjectName
if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '' or ocUserName == '' or ocPassword == '' or ocProjectName == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
logging.debug('Building on server: ' + lIpAddr)
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
self.testCase_id = HTML.testCase_id
# on RedHat/CentOS .git extension is mandatory
result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
if result is not None:
full_ran_repo_name = self.ranRepository.replace('git/', 'git')
else:
full_ran_repo_name = self.ranRepository + '.git'
mySSH.command('echo ' + lPassWord + ' | sudo rm -Rf ' + lSourcePath, '\$', 30)
mySSH.command('mkdir -p ' + lSourcePath, '\$', 5)
mySSH.command('cd ' + lSourcePath, '\$', 5)
mySSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600)
# Raphael: here add a check if git clone or git fetch went smoothly
mySSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
mySSH.command('git config user.name "OAI Jenkins"', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30)
mySSH.command('mkdir -p cmake_targets/log', '\$', 5)
# if the commit ID is provided use it to point to it
if self.ranCommitID != '':
mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
if self.ranAllowMerge:
imageTag = "ci-temp"
if self.ranTargetBranch == '':
if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'):
mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5)
else:
logging.debug('Merging with the target branch: ' + self.ranTargetBranch)
mySSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
else:
imageTag = "develop"
# 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' oai-physim:" + imageTag, '\$', 60)
if mySSH.getBefore().count('no such image') != 0:
logging.error('\u001B[1m No such image oai-physim\u001B[0m')
mySSH.close()
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.PHYSIM_IMAGE_ABSENT)
RAN.prematureExit = True
return
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('\u001B[1m oai-physim size is ' + ('%.0f' % imageSize) + ' kbytes\u001B[0m')
else:
imageSize = imageSize / 1000
if imageSize < 1000:
logging.debug('\u001B[1m oai-physim size is ' + ('%.0f' % imageSize) + ' Mbytes\u001B[0m')
else:
imageSize = imageSize / 1000
logging.debug('\u001B[1m oai-physim is ' + ('%.3f' % imageSize) + ' Gbytes\u001B[0m')
else:
logging.debug('oai-physim 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()
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL)
RAN.prematureExit = True
return
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()
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_PROJECT_FAIL)
RAN.prematureExit = True
return
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()
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL)
RAN.prematureExit = True
return
else:
logging.debug('\u001B[1m Podman Login to OC Cluster Registry Successfully\u001B[0m')
time.sleep(2)
mySSH.command('oc create -f openshift/oai-physim-image-stream.yml', '\$', 6)
if mySSH.getBefore().count('(AlreadyExists):') == 0 and mySSH.getBefore().count('created') == 0:
logging.error(f'\u001B[1m Image Stream "oai-physim" Creation Failed on OC Cluster {ocProjectName}\u001B[0m')
mySSH.close()
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_IS_FAIL)
RAN.prematureExit = True
return
else:
logging.debug(f'\u001B[1m Image Stream "oai-physim" created on OC project {ocProjectName}\u001B[0m')
time.sleep(2)
mySSH.command(f'sudo podman tag oai-physim:{imageTag} default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
time.sleep(2)
mySSH.command(f'sudo podman push default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag} --tls-verify=false', '\$', 30)
if mySSH.getBefore().count('Storing signatures') == 0:
logging.error('\u001B[1m Image "oai-physim" push to OC Cluster Registry Failed\u001B[0m')
mySSH.close()
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_IS_FAIL)
RAN.prematureExit = True
return
else:
logging.debug('\u001B[1m Image "oai-physim" push to OC Cluster Registry Successfully\u001B[0m')
# Using helm charts deployment
time.sleep(5)
mySSH.command(f'sed -i -e "s#TAG#{imageTag}#g" ./charts/physims/values.yaml', '\$', 6)
mySSH.command('helm install physim ./charts/physims/ | tee -a cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
if mySSH.getBefore().count('STATUS: deployed') == 0:
logging.error('\u001B[1m Deploying PhySim Failed using helm chart on OC Cluster\u001B[0m')
mySSH.command('helm uninstall physim >> cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
isFinished1 = False
while(isFinished1 == False):
time.sleep(20)
mySSH.command('oc get pods -l app.kubernetes.io/instance=physim', '\$', 6, resync=True)
if re.search('No resources found', mySSH.getBefore()):
isFinished1 = True
mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
mySSH.command('oc delete is oai-physim', '\$', 6)
mySSH.close()
self.AnalyzeLogFile_phySim(HTML)
RAN.prematureExit = True
return
else:
logging.debug('\u001B[1m Deployed PhySim Successfully using helm chart\u001B[0m')
isRunning = False
count = 0
while(count < 2 and isRunning == False):
time.sleep(60)
mySSH.command('oc get pods -o wide -l app.kubernetes.io/instance=physim | tee -a cmake_targets/log/physim_pods_summary.txt', '\$', 6, resync=True)
if mySSH.getBefore().count('Running') == 12:
logging.debug('\u001B[1m Running the physim test Scenarios\u001B[0m')
isRunning = True
podNames = re.findall('oai-[\S\d\w]+', mySSH.getBefore())
count +=1
if isRunning == False:
logging.error('\u001B[1m Some PODS Running FAILED \u001B[0m')
mySSH.command('oc get pods -l app.kubernetes.io/instance=physim 2>&1 | tee -a cmake_targets/log/physim_pods_summary.txt', '\$', 6)
mySSH.command('helm uninstall physim >> cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
self.AnalyzeLogFile_phySim(HTML)
isFinished1 = False
while(isFinished1 == False):
time.sleep(20)
mySSH.command('oc get pods -l app.kubernetes.io/instance=physim', '\$', 6, resync=True)
if re.search('No resources found', mySSH.getBefore()):
isFinished1 = True
mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
mySSH.command('oc delete is oai-physim', '\$', 6)
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_PHYSIM_DEPLOY_FAIL)
HTML.CreateHtmlTestRowPhySimTestResult(self.testSummary,self.testResult)
RAN.prematureExit = True
return
# Waiting to complete the running test
count = 0
isFinished = False
# doing a deep copy!
tmpPodNames = podNames.copy()
while(count < 28 and isFinished == False):
time.sleep(60)
for podName in tmpPodNames:
mySSH.command2(f'oc logs --tail=1 {podName} 2>&1', 6, silent=True)
if mySSH.cmd2Results.count('FINISHED') != 0:
logging.debug(podName + ' is finished')
tmpPodNames.remove(podName)
if not tmpPodNames:
isFinished = True
count += 1
if isFinished:
logging.debug('\u001B[1m PhySim test is Complete\u001B[0m')
# Getting the logs of each executables running in individual pods
for podName in podNames:
mySSH.command(f'oc logs {podName} >> cmake_targets/log/physim_test.txt 2>&1', '\$', 15, resync=True)
time.sleep(30)
# UnDeploy the physical simulator pods
mySSH.command('helm uninstall physim | tee -a cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
isFinished1 = False
while(isFinished1 == False):
time.sleep(20)
mySSH.command('oc get pods -l app.kubernetes.io/instance=physim', '\$', 6, resync=True)
if re.search('No resources found', mySSH.getBefore()):
isFinished1 = True
if isFinished1 == True:
logging.debug('\u001B[1m UnDeployed PhySim Successfully on OC Cluster\u001B[0m')
mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
mySSH.command('oc delete is oai-physim', '\$', 6)
logging.debug('\u001B[1m Deleted the Image and ImageStream\u001B[0m')
mySSH.command('oc logout', '\$', 6)
mySSH.close()
self.AnalyzeLogFile_phySim(HTML)
if self.testStatus:
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlTestRowPhySimTestResult(self.testSummary,self.testResult)
logging.info('\u001B[1m Physical Simulator Pass\u001B[0m')
else:
RAN.prematureExit = True
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlTestRowPhySimTestResult(self.testSummary,self.testResult)
logging.info('\u001B[1m Physical Simulator Fail\u001B[0m')
def AnalyzeLogFile_phySim(self, HTML):
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
lPassWord = self.eNBPassword
lSourcePath = self.eNBSourceCodePath
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
mySSH.command('cd ' + lSourcePath, '\$', 5)
mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
mySSH.command('mkdir -p physim_test_log_' + self.testCase_id, '\$', 5)
mySSH.command('cp log/physim_* ' + 'physim_test_log_' + self.testCase_id, '\$', 5)
if not os.path.exists(f'./physim_test_logs_{self.testCase_id}'):
os.mkdir(f'./physim_test_logs_{self.testCase_id}')
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/physim_test_log_' + self.testCase_id + '/*', './physim_test_logs_' + self.testCase_id)
mySSH.command('rm -rf ./physim_test_log_'+ self.testCase_id, '\$', 5)
mySSH.close()
# physim test log analysis
nextt = 0
if (os.path.isfile(f'./physim_test_logs_{self.testCase_id}/physim_test.txt')):
with open(f'./physim_test_logs_{self.testCase_id}/physim_test.txt', 'r') as logfile:
for line in logfile:
if re.search('execution 015', str(line)) or re.search('Bypassing compilation', str(line)):
nextt = 1
elif nextt == 1:
if not re.search('Test Results', str(line)):
nextt = 0
ret2 = re.search('T[^\n]*', str(line))
if ret2 is not None:
ret3 = ret2.group()
ret3 = ret3.replace("", "")
if re.search('execution 015', str(line)):
self.testCount[0] += 1
testName = line.split()
ret1 = re.search('Result = PASS', str(line))
if ret1 is not None:
self.testResult[testName[1]] = [ret3, 'PASS']
self.testCount[1] += 1
else:
self.testResult[testName[1]] = [ret3, 'FAIL']
self.testCount[2] += 1
self.testSummary['Nbtests'] = self.testCount[0]
self.testSummary['Nbpass'] = self.testCount[1]
self.testSummary['Nbfail'] = self.testCount[2]
if self.testSummary['Nbfail'] == 0:
self.testStatus = True
return 0
+2 -2
View File
@@ -101,7 +101,7 @@ class StaticCodeAnalysis():
# on RedHat/CentOS .git extension is mandatory # on RedHat/CentOS .git extension is mandatory
result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
if result is not None: if result is not None:
full_ran_repo_name = self.ranRepository full_ran_repo_name = self.ranRepository.replace('git/', 'git')
else: else:
full_ran_repo_name = self.ranRepository + '.git' full_ran_repo_name = self.ranRepository + '.git'
mySSH.command('mkdir -p ' + lSourcePath, '\$', 5) mySSH.command('mkdir -p ' + lSourcePath, '\$', 5)
@@ -115,7 +115,7 @@ class StaticCodeAnalysis():
mySSH.command('mkdir -p cmake_targets/log', '\$', 5) mySSH.command('mkdir -p cmake_targets/log', '\$', 5)
# if the commit ID is provided use it to point to it # if the commit ID is provided use it to point to it
if self.ranCommitID != '': if self.ranCommitID != '':
mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 5) mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:xenial || true', '\$', 60) mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:xenial || true', '\$', 60)
mySSH.command('docker build --tag oai-cppcheck:xenial --file ci-scripts/docker/Dockerfile.cppcheck.xenial . > cmake_targets/log/cppcheck-xenial.txt 2>&1', '\$', 600) mySSH.command('docker build --tag oai-cppcheck:xenial --file ci-scripts/docker/Dockerfile.cppcheck.xenial . > cmake_targets/log/cppcheck-xenial.txt 2>&1', '\$', 600)
+5 -5
View File
@@ -92,9 +92,9 @@ gNBs =
prach_msg1_FDM = 0; prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 74; prach_msg1_FrequencyStart = 74;
zeroCorrelationZoneConfig = 13; zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -118; #preambleReceivedTargetPower = -118;
#preambleReceivedTargetPower = -104; #preambleReceivedTargetPower = -104;
#preambleReceivedTargetPower = -108; preambleReceivedTargetPower = -108;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6; preambleTransMax = 6;
#powerRampingStep #powerRampingStep
@@ -124,13 +124,13 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B # 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0, restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements) # pusch-ConfigCommon (up to 16 elements)
initialULBWPk2_0 = 6; # used for UL slot initialULBWPk2_0 = 2; # used for UL slot
initialULBWPmappingType_0 = 1 initialULBWPmappingType_0 = 1
initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12
initialULBWPk2_1 = 6; # used for mixed slot initialULBWPk2_1 = 2; # used for mixed slot
initialULBWPmappingType_1 = 1; initialULBWPmappingType_1 = 1;
initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 initialULBWPstartSymbolAndLength_1 = 69; # this is SS=10 L=2
initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPk2_2 = 7; # used for Msg.3 during RA
initialULBWPmappingType_2 = 1; initialULBWPmappingType_2 = 1;
@@ -244,7 +244,7 @@ MACRLCs = (
THREAD_STRUCT = ( THREAD_STRUCT = (
{ {
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
worker_config = "ENABLE"; worker_config = "WORKER_ENABLE";
} }
); );
@@ -260,11 +260,11 @@ RUs = (
local_rf = "yes" local_rf = "yes"
nb_tx = 1 nb_tx = 1
nb_rx = 1 nb_rx = 1
att_tx = 0 att_tx = 3
att_rx = 0; att_rx = 0;
bands = [7]; bands = [7];
max_pdschReferenceSignalPower = -27; max_pdschReferenceSignalPower = -27;
max_rxgain = 118; max_rxgain = 115;
eNB_instances = [0]; eNB_instances = [0];
# clock_src = "external"; # clock_src = "external";
} }

Some files were not shown because too many files have changed in this diff Show More