From 558c274c0a8f5736e05f5d40d4279d13dde975c1 Mon Sep 17 00:00:00 2001
From: "Sridhar K. N. Rao" <sridhar.rao@spirent.com>
Date: Wed, 4 Aug 2021 17:28:26 +0530
Subject: Enhance Pod-Deployment using Python-API.

This patch enhances the pod-deployment process using Python-API.

Minor bug fixes
Remove WIP

Signed-off-by: Sridhar K. N. Rao <sridhar.rao@spirent.com>
Change-Id: Ib44b4934129b10333a0d81e1807417850dfa2934
---
 pods/papi/k8scmdrun.py | 112 +++++++++++++++++++++++++++++++++++++++++++++++++
 pods/papi/papi.py      |  51 ++++++++++++++++++----
 2 files changed, 155 insertions(+), 8 deletions(-)
 create mode 100644 pods/papi/k8scmdrun.py

(limited to 'pods')

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):
         """
-- 
cgit 1.2.3-korg