Commit 41e81915 authored by Robert Schmidt's avatar Robert Schmidt

Improve cls_module_ue.py

parent 917bea36
...@@ -28,164 +28,186 @@ ...@@ -28,164 +28,186 @@
import os import os
import sys import sys
import logging import logging
#to create a SSH object locally in the methods
import sshconnection
#time.sleep #time.sleep
import time import time
import re import re
import subprocess import subprocess
from datetime import datetime from datetime import datetime
import yaml
#for log rotation mgt #for log rotation mgt
import cls_log_mgt import cls_log_mgt
import cls_cmd
class Module_UE: class Module_UE:
def __init__(self,Module): def __init__(self, module_name, filename="ci_ueinfra.yaml"):
#create attributes as in the Module dictionary with open(filename, 'r') as f:
for k, v in Module.items(): all_ues = yaml.load(f, Loader=yaml.FullLoader)
setattr(self, k, v) m = all_ues.get(module_name)
self.UEIPAddress = "" if m is None:
#dictionary linking command names and related module scripts raise Exception(f'no such module name "{module_name}" in "{filename}"')
self.cmd_dict= {"wup": self.WakeupScript,"detach":self.DetachScript}#dictionary of function scripts self.module_name = module_name
self.ue_trace='' self.host = m['Host']
self.cmd_dict = {
"attach": m.get('AttachScript'),
"detach": m.get('DetachScript'),
"initialize": m.get('InitScript'),
"terminate": m.get('TermScript'),
"getNetwork": m.get('UENetworkScript'),
"check": m.get('CheckStatusScript'),
"dataEnable": m.get('DataEnableScript'),
"dataDisable": m.get('DataDisableScript'),
}
self.interface = m.get('IF')
self.MTU = m.get('MTU')
self.trace = m.get('trace') == True
self.logStore = m.get('LogStore')
self.cmd_prefix = m.get('CmdPrefix')
logging.info(f'initialized UE {self.module_name}@{self.host} from {filename}')
def __str__(self):
return f"{self.module_name}@{self.host} [IP: {self.getIP()}]"
def __repr__(self):
return self.__str__()
def _command(self, cmd, silent = False):
if cmd is None:
raise Exception("no command provided")
if self.host == "" or self.host == "localhost":
c = cls_cmd.LocalCmd()
else:
c = cls_cmd.RemoteCmd(self.host)
response = c.run(cmd, silent=silent)
c.close()
return response.stdout
#-----------------$ #-----------------$
#PUBLIC Methods$ #PUBLIC Methods$
#-----------------$ #-----------------$
#this method checks if the specified Process is running on the server hosting the module def initialize(self):
#if not it will be started if self.trace:
def CheckCMProcess(self,CNType): raise Exception("UE tracing not implemented yet")
HOST=self.HostUsername+'@'+self.HostIPAddress self._enableTrace()
COMMAND="ps aux | grep --colour=never " + self.Process['Name'] + " | grep -v grep " # we first terminate to make sure the UE has been stopped
logging.debug(COMMAND) if self.cmd_dict["detach"]:
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE) self._command(self.cmd_dict["detach"], silent=True)
result = ssh.stdout.readlines() self._command(self.cmd_dict["terminate"], silent=True)
if len(result)!=0: self._command(self.cmd_dict["initialize"])
logging.debug(self.Process['Name'] + " process found")
return True def terminate(self):
else:#start process and check again self._command(self.cmd_dict["terminate"])
logging.debug(self.Process['Name'] + " process NOT found") if self.trace:
#starting the process raise Exception("UE tracing not implemented yet")
logging.debug('Starting ' + self.Process['Name']) self._disableTrace()
mySSH = sshconnection.SSHConnection() return self._logCollect()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword) return None
mySSH.command('echo ' + self.HostPassword + ' | sudo -S rm -f /tmp/quectel-cm.log','\$',5)
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S stdbuf -o0 ' + self.Process['Cmd'] + ' ' + self.Process['Apn'][CNType] + ' > /tmp/quectel-cm.log 2>&1 &','\$',5) def attach(self, attach_tries = 4, attach_timeout = 60):
mySSH.close() ip = None
#checking the process while attach_tries > 0:
self._command(self.cmd_dict["attach"])
timeout = attach_timeout
logging.debug("Waiting for IP address to be assigned")
while timeout > 0 and not ip:
time.sleep(5) time.sleep(5)
HOST=self.HostUsername+'@'+self.HostIPAddress timeout -= 5
COMMAND="ps aux | grep --colour=never " + self.Process['Name'] + " | grep -v grep " ip = self.getIP()
logging.debug(COMMAND) if ip:
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE) break
result = ssh.stdout.readlines() logging.warning(f"UE did not receive IP address after {attach_timeout} s, detaching")
if len(result)!=0: attach_tries -= 1
logging.debug(self.Process['Name'] + " process found") self._command(self.cmd_dict["detach"])
return True time.sleep(5)
if ip:
logging.debug(f'\u001B[1mUE IP Address is {ip}\u001B[0m')
else: else:
logging.debug(self.Process['Name'] + " process NOT found") logging.debug('\u001B[1;37;41mUE IP Address Not Found!\u001B[0m')
return False return ip
#Generic command function, using function pointers dictionary def detach(self):
def Command(self,cmd): self._command(self.cmd_dict["detach"])
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()
def check(self):
cmd = self.cmd_dict["check"]
if cmd:
return self._command(cmd)
else:
logging.warning(f"requested status check of UE {self.getName()}, but operation is not supported")
return f"UE {self.getName()} does not support status checking"
#this method retrieves the Module IP address (not the Host IP address) def dataEnable(self):
def GetModuleIPAddress(self): cmd = self.cmd_dict["dataEnable"]
HOST=self.HostUsername+'@'+self.HostIPAddress if cmd:
response= [] self._command(cmd)
tentative = 8 return True
while (len(response)==0) and (tentative>0):
COMMAND="ip a show dev " + self.UENetwork + " | grep --colour=never inet | grep " + self.UENetwork
if tentative == 8:
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(2)
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: else:
logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m') message = f"requested enabling data of UE {self.getName()}, but operation is not supported"
return -1 logging.error(message)
return False
def dataDisable(self):
cmd = self.cmd_dict["dataDisable"]
if cmd:
self._command(cmd)
return True
else: else:
logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m') message = f"requested disabling data of UE {self.getName()}, but operation is not supported"
return -1 logging.error(message)
return False
def CheckModuleMTU(self):
HOST=self.HostUsername+'@'+self.HostIPAddress def getIP(self):
response= [] output = self._command(self.cmd_dict["getNetwork"], silent=True)
tentative = 3 result = re.search('inet (?P<ip>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', output)
while (len(response)==0) and (tentative>0): if result and result.group('ip'):
COMMAND="ip a show dev " + self.UENetwork + " | grep --colour=never mtu" ip = result.group('ip')
logging.debug(COMMAND) return ip
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE) return None
response = ssh.stdout.readlines()
tentative-=1 def checkMTU(self):
time.sleep(10) output = self._command(self.cmd_dict["getNetwork"], silent=True)
if (tentative==0) and (len(response)==0): result = re.search('mtu (?P<mtu>[0-9]+)', output)
logging.debug('\u001B[1;37;41m Module NIC MTU Not Found! Time expired \u001B[0m') if result and result.group('mtu') and int(result.group('mtu')) == self.MTU:
return -1
else: #check response
result = re.search('mtu (?P<mtu>[0-9]+)', response[0].decode("utf-8") )
if result is not None:
if (result.group('mtu') is not None) and (str(result.group('mtu'))==str(self.MTU)) :
logging.debug('\u001B[1mUE Module NIC MTU is ' + str(self.MTU) + ' as expected\u001B[0m') logging.debug('\u001B[1mUE Module NIC MTU is ' + str(self.MTU) + ' as expected\u001B[0m')
return 0 return True
else:
logging.debug('\u001B[1;37;41m Incorrect Module NIC MTU ' + str(result.group('mtu')) + '! Expected : ' + str(self.MTU) + '\u001B[0m')
return -1
else: else:
logging.debug('\u001B[1;37;41m Module NIC MTU Not Found! \u001B[0m') logging.debug('\u001B[1;37;41m Incorrect Module NIC MTU or MTU not found! Expected: ' + str(self.MTU) + '\u001B[0m')
return -1 return False
def getName(self):
return self.module_name
def getIFName(self):
return self.interface
def EnableTrace(self): def getHost(self):
if self.ue_trace=="yes": return self.host
def getCmdPrefix(self):
return self.cmd_prefix if self.cmd_prefix else ""
def _enableTrace(self):
raise Exception("not implemented")
mySSH = sshconnection.SSHConnection() mySSH = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword) mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
#delete old artifacts #delete old artifacts
mySSH.command('echo ' + self.HostPassword + ' | sudo -S rm -rf ci_qlog','\$',5) mySSH.command('echo ' + ' ' + ' | sudo -S rm -rf ci_qlog','\$',5)
#start Trace, artifact is created in home dir #start Trace, artifact is created in home dir
mySSH.command('echo $USER; nohup sudo -E QLog/QLog -s ci_qlog -f NR5G.cfg > /dev/null 2>&1 &','\$', 5) mySSH.command('echo $USER; nohup sudo -E QLog/QLog -s ci_qlog -f NR5G.cfg > /dev/null 2>&1 &','\$', 5)
mySSH.close() mySSH.close()
def DisableTrace(self): def _disableTrace(self):
raise Exception("not implemented")
mySSH = sshconnection.SSHConnection() mySSH = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword) mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
mySSH.command('echo ' + self.HostPassword + ' | sudo -S killall --signal=SIGINT *QLog*', '\$',5) mySSH.command('echo ' + ' ' + ' | sudo -S killall --signal=SIGINT *QLog*', '\$',5)
mySSH.close() mySSH.close()
def DisableCM(self): def _logCollect(self):
mySSH = sshconnection.SSHConnection() raise Exception("not implemented")
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 = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword) mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
#archive qlog to USB stick in /media/usb-drive/ci_qlogs with datetime suffix #archive qlog to USB stick in /media/usb-drive/ci_qlogs with datetime suffix
...@@ -194,11 +216,9 @@ class Module_UE: ...@@ -194,11 +216,9 @@ class Module_UE:
source='ci_qlog' source='ci_qlog'
destination= self.LogStore + '/ci_qlog_'+now_string+'.zip' destination= self.LogStore + '/ci_qlog_'+now_string+'.zip'
#qlog artifact is zipped into the target folder #qlog artifact is zipped into the target folder
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S zip -r '+destination+' '+source+' > /dev/null 2>&1 &','\$', 10) mySSH.command('echo $USER; echo ' + ' ' + ' | nohup sudo -S zip -r '+destination+' '+source+' > /dev/null 2>&1 &','\$', 10)
mySSH.close() mySSH.close()
#post action : log cleaning to make sure enough space is reserved for the next run #post action : log cleaning to make sure enough space is reserved for the next run
Log_Mgt=cls_log_mgt.Log_Mgt(self.HostUsername,self.HostIPAddress, self.HostPassword, self.LogStore) Log_Mgt=cls_log_mgt.Log_Mgt(self.HostUsername,self.HostIPAddress, self.HostPassword, self.LogStore)
Log_Mgt.LogRotation()
else:
destination=""
return destination return destination
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment