nfvbenchvm: refactor wait for VPP service
[nfvbench.git] / nfvbench / utils.py
index 2ce735b..07a38cb 100644 (file)
@@ -13,6 +13,7 @@
 #    under the License.
 
 import glob
+import time
 from math import gcd
 from math import isnan
 import os
@@ -26,6 +27,7 @@ from functools import wraps
 import json
 from .log import LOG
 from nfvbench.traffic_gen.traffic_utils import multiplier_map
+from novaclient.exceptions import NotFound
 
 class TimeoutError(Exception):
     pass
@@ -51,7 +53,7 @@ def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):
 
 
 def save_json_result(result, json_file, std_json_path, service_chain, service_chain_count,
-                     flow_count, frame_sizes):
+                     flow_count, frame_sizes, user_id=None, group_id=None):
     """Save results in json format file."""
     filepaths = []
     if json_file:
@@ -64,13 +66,18 @@ def save_json_result(result, json_file, std_json_path, service_chain, service_ch
     if filepaths:
         for file_path in filepaths:
             LOG.info('Saving results in json file: %s...', file_path)
-            with open(file_path, 'w') as jfp:
+            with open(file_path, 'w', encoding="utf-8") as jfp:
                 json.dump(result,
                           jfp,
                           indent=4,
                           sort_keys=True,
                           separators=(',', ': '),
                           default=lambda obj: obj.to_json())
+                # possibly change file ownership
+                if group_id is None:
+                    group_id = user_id
+                if user_id is not None:
+                    os.chown(file_path, user_id, group_id)
 
 
 def dict_to_json_dict(record):
@@ -120,11 +127,11 @@ def get_intel_pci(nic_slot=None, nic_ports=None):
         trex_base_dir = '/opt/trex'
         contents = os.listdir(trex_base_dir)
         trex_dir = os.path.join(trex_base_dir, contents[0])
-        process = subprocess.Popen(['python', 'dpdk_setup_ports.py', '-s'],
-                                   cwd=trex_dir,
-                                   stdout=subprocess.PIPE,
-                                   stderr=subprocess.PIPE)
-        devices, _ = process.communicate()
+        with subprocess.Popen(['python', 'dpdk_setup_ports.py', '-s'],
+                              cwd=trex_dir,
+                              stdout=subprocess.PIPE,
+                              stderr=subprocess.PIPE) as process:
+            devices, _ = process.communicate()
     except Exception:
         devices = ''
 
@@ -140,10 +147,10 @@ def get_intel_pci(nic_slot=None, nic_ports=None):
             intf_name = glob.glob("/sys/bus/pci/devices/%s/net/*" % port[0])
             if intf_name:
                 intf_name = intf_name[0][intf_name[0].rfind('/') + 1:]
-                process = subprocess.Popen(['ip', '-o', '-d', 'link', 'show', intf_name],
-                                           stdout=subprocess.PIPE,
-                                           stderr=subprocess.PIPE)
-                intf_info, _ = process.communicate()
+                with subprocess.Popen(['ip', '-o', '-d', 'link', 'show', intf_name],
+                                      stdout=subprocess.PIPE,
+                                      stderr=subprocess.PIPE) as process:
+                    intf_info, _ = process.communicate()
                 if re.search('team_slave|bond_slave', intf_info.decode("utf-8")):
                     device_ports_list[port[0].split('.')[0]]['busy'] = True
         for port in matches:
@@ -155,7 +162,6 @@ def get_intel_pci(nic_slot=None, nic_ports=None):
     return pcis
 
 
-
 def parse_flow_count(flow_count):
     flow_count = str(flow_count)
     input_fc = flow_count
@@ -247,3 +253,39 @@ def find_max_size(max_size, tuples, flow):
         if flow % i == 0:
             return int(i)
     return 1
+
+
+def delete_server(nova_client, server):
+    try:
+        LOG.info('Deleting instance %s...', server.name)
+        nova_client.servers.delete(server.id)
+    except Exception:
+        LOG.exception("Instance %s deletion failed", server.name)
+
+
+def instance_exists(nova_client, server):
+    try:
+        nova_client.servers.get(server.id)
+    except NotFound:
+        return False
+    return True
+
+
+def waiting_servers_deletion(nova_client, servers):
+    LOG.info('    Waiting for %d instances to be fully deleted...', len(servers))
+    retry_count = 15 + len(servers) * 5
+    while True:
+        retry_count -= 1
+        servers = [server for server in servers if instance_exists(nova_client, server)]
+        if not servers:
+            break
+
+        if retry_count:
+            LOG.info('    %d yet to be deleted by Nova, retries left=%d...',
+                     len(servers), retry_count)
+            time.sleep(2)
+        else:
+            LOG.warning(
+                '    instance deletion verification time-out: %d still not deleted',
+                len(servers))
+            break