diff options
-rw-r--r-- | pods/papi/k8scmdrun.py | 112 | ||||
-rw-r--r-- | pods/papi/papi.py | 51 |
2 files changed, 155 insertions, 8 deletions
diff --git a/pods/papi/k8scmdrun.py b/pods/papi/k8scmdrun.py new file mode 100644 index 00000000..2fb1a62e --- /dev/null +++ b/pods/papi/k8scmdrun.py @@ -0,0 +1,112 @@ +# Copyright 2021 Spirent Communications. +# +# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +# +# 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. +""" +Run commands inside the pod for post-deployment configuration +""" + +import re +import os +from kubernetes import client, config +from kubernetes.client.rest import ApiException +from kubernetes.stream import stream + +def execute_command(api_instance, pod_info, exec_command): + """ + Execute a command inside a specified pod + exec_command = list of strings + """ + name = pod_info['name'] + resp = None + try: + resp = api_instance.read_namespaced_pod(name=name, + namespace='default') + except ApiException as e: + if e.status != 404: + print("Unknown error: %s" % e) + exit(1) + if not resp: + print("Pod %s does not exist. Creating it..." % name) + return -1 + + # Calling exec and waiting for response + resp = stream(api_instance.connect_get_namespaced_pod_exec, + name, + 'default', + command=exec_command, + stderr=True, stdin=False, + stdout=True, tty=False) + print("Response: " + resp) + return resp + +def get_virtual_sockets(api_instance, podname, namespace): + """ + Memif or VhostUser Sockets + """ + socket_files = [] + pinfo = {'name': podname, + 'pod_ip':'', + 'namespace': namespace} + cmd = ['cat', '/etc/podnetinfo/annotations'] + resp = execute_command(api_instance, pinfo, cmd) + # Remove unnecessary elements + results = re.sub(r"(\\n|\"|\n|\\|\]|\{|\}|\[)", "", resp).strip() + # Remove unnecessary spaces + results = re.sub(r"\s+","", results, flags=re.UNICODE) + # Get the RHS values + output = results.split('=') + for out in output: + if 'socketfile' in out: + out2 = out.split(',') + for rout in out2: + if 'socketfile' in rout: + print(rout[11:]) + socket_files.append(rout[11:]) + + +def get_sriov_interfaces(api_instance, podname, namespace): + """ + Get SRIOV PIDs. + """ + pinfo = {'name': podname, + 'pod_ip':'', + 'namespace': namespace} + cmd = ['cat', '/etc/podnetinfo/annotations'] + response = execute_command(api_instance, pinfo, cmd) + # Remove unnecessary elements + results = re.sub(r"(\\n|\"|\n|\\|\]|\{|\}|\[)", "", response).strip() + # Remove unnecessary spaces + results = re.sub(r"\s+","", results, flags=re.UNICODE) + # Get the RHS values + output = results.split('=') + names = [] + ifs = [] + for out in output: + if 'interface' in out: + out2 = out.split(',') + for rout in out2: + if 'interface' in rout: + ifs.append(rout[10:]) + elif 'name' in rout: + names.append(rout[5:]) + res = {names[i]: ifs[i] for i in range(len(names))} + +def start_fowarding_app(api_instance, podname, namespace, appname): + """ + Start the Forwarding Application + """ + pinfo = {'name': podname, + 'pod_ip':'', + 'namespace': namespace} + cmd = [appname, '&'] + response = execute_command(api_instance, pinfo, cmd) diff --git a/pods/papi/papi.py b/pods/papi/papi.py index 5c15fa04..67cc3bc5 100644 --- a/pods/papi/papi.py +++ b/pods/papi/papi.py @@ -1,4 +1,4 @@ -# Copyright 2020 University Of Delhi. +# Copyright 2021 University Of Delhi, Spirent Communications # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -55,8 +55,11 @@ class Papi(IPod): namespace = 'default' pod_manifests = S.getValue('POD_MANIFEST_FILEPATH') pod_count = int(S.getValue('POD_COUNT')) - #namespace = 'vswitchperf' - # replace_namespace(api, namespace) + if S.hasValue('POD_NAMESPACE'): + namespace = S.getValue('POD_NAMESPACE') + else: + namespace = 'default' + dep_pod_list = [] # sriov configmap if S.getValue('PLUGIN') == 'sriov': @@ -70,8 +73,7 @@ class Papi(IPod): group = 'k8s.cni.cncf.io' version = 'v1' kind_plural = 'network-attachment-definitions' - api = client.CustomObjectsApi() - + api = client.CustomObjectsApi() assert pod_count <= len(pod_manifests) for nad_filepath in S.getValue('NETWORK_ATTACHMENT_FILEPATH'): @@ -87,10 +89,10 @@ class Papi(IPod): #create pod workloads api = client.CoreV1Api() - for count in range(pod_count): + dep_pod_info = {} pod_manifest = load_manifest(pod_manifests[count]) - + dep_pod_info['name'] = pod_manifest["metadata"]["name"] try: response = api.create_namespaced_pod(namespace, pod_manifest) self._logger.info(str(response)) @@ -98,7 +100,40 @@ class Papi(IPod): except ApiException as err: raise Exception from err - time.sleep(12) + # Wait for the pod to start + time.sleep(5) + status = "Unknown" + count = 0 + while True: + if count == 10: + break + try: + response = api.read_namespaced_pod_status(dep_pod_info['name'], + namespace) + status = response.status.phase + except ApiException as err: + raise Exception from err + if (status == "Running" + or status == "Failed" + or status == "Unknown"): + break + else: + time.sleep(5) + count = count + 1 + # Now Get the Pod-IP + try: + response = api.read_namespaced_pod_status(dep_pod_info['name'], + namespace) + dep_pod_info['pod_ip'] = response.status.pod_ip + except ApiException as err: + raise Exception from err + dep_pod_info['namespace'] = namespace + dep_pod_list.append(dep_pod_info) + cmd = ['cat', '/etc/podnetinfo/annotations'] + execute_command(api, dep_pod_info, cmd) + + S.setValue('POD_LIST',dep_pod_list) + return dep_pod_list def terminate(self): """ |