Assign static IP to VM for standalone context 59/61459/5
authorStepan Andrushko <stepanx.andrushko@intel.com>
Tue, 28 Aug 2018 10:30:19 +0000 (13:30 +0300)
committerStepan Andrushko <stepanx.andrushko@intel.com>
Wed, 29 Aug 2018 17:27:00 +0000 (20:27 +0300)
During VM spawning IP address should be assigned by DHCP server in
the local network. Sometimes DHCP server is not capable to assign IP
address. So, need to add static IP address.

JIRA: YARDSTICK-1402

Change-Id: Ie59c340eb88eddcaff043496fc20aa48b49205ec
Signed-off-by: Stepan Andrushko <stepanx.andrushko@intel.com>
yardstick/benchmark/contexts/standalone/model.py
yardstick/benchmark/contexts/standalone/ovs_dpdk.py
yardstick/benchmark/contexts/standalone/sriov.py
yardstick/tests/unit/benchmark/contexts/standalone/test_model.py
yardstick/tests/unit/benchmark/contexts/standalone/test_ovs_dpdk.py
yardstick/tests/unit/benchmark/contexts/standalone/test_sriov.py

index 962cb48..fa78fc1 100644 (file)
@@ -100,6 +100,19 @@ users:
 EOF
 """
 
+NETWORK_DATA_TEMPLATE = """
+cat > {network_file} <<EOF
+#cloud-config
+version: 2
+ethernets:
+  ens3:
+    match:
+      mac_address: {mac_address}
+    addresses:
+      - {ip_address}
+EOF
+"""
+
 WAIT_FOR_BOOT = 30
 
 
@@ -370,7 +383,7 @@ class Libvirt(object):
         return ET.tostring(root)
 
     @staticmethod
-    def gen_cdrom_image(connection, file_path, vm_name, vm_user, key_filename):
+    def gen_cdrom_image(connection, file_path, vm_name, vm_user, key_filename, mac, ip):
         """Generate ISO image for CD-ROM """
 
         user_config = ["    - name: {user_name}",
@@ -381,6 +394,7 @@ class Libvirt(object):
 
         meta_data = "/tmp/meta-data"
         user_data = "/tmp/user-data"
+        network_data = "/tmp/network-config"
         with open(".".join([key_filename, "pub"]), "r") as pub_key_file:
             pub_key_str = pub_key_file.read().rstrip()
         user_conf = os.linesep.join(user_config).format(pub_key_str=pub_key_str, user_name=vm_user)
@@ -388,10 +402,13 @@ class Libvirt(object):
         cmd_lst = [
             "touch %s" % meta_data,
             USER_DATA_TEMPLATE.format(user_file=user_data, host=vm_name, user_config=user_conf),
-            "genisoimage -output {0} -volid cidata -joliet -r {1} {2}".format(file_path,
-                                                                              meta_data,
-                                                                              user_data),
-            "rm {0} {1}".format(meta_data, user_data),
+            NETWORK_DATA_TEMPLATE.format(network_file=network_data, mac_address=mac,
+                                         ip_address=ip),
+            "genisoimage -output {0} -volid cidata -joliet -r {1} {2} {3}".format(file_path,
+                                                                                  meta_data,
+                                                                                  user_data,
+                                                                                  network_data),
+            "rm {0} {1} {2}".format(meta_data, user_data, network_data),
         ]
         for cmd in cmd_lst:
             LOG.info(cmd)
@@ -537,7 +554,7 @@ class StandaloneContextHelper(object):
         return nodes
 
     @classmethod
-    def check_update_key(cls, connection, node, vm_name, id_name, cdrom_img):
+    def check_update_key(cls, connection, node, vm_name, id_name, cdrom_img, mac):
         # Generate public/private keys if private key file is not provided
         user_name = node.get('user')
         if not user_name:
@@ -552,7 +569,9 @@ class StandaloneContextHelper(object):
             node['key_filename'] = key_filename
         # Update image with public key
         key_filename = node.get('key_filename')
-        Libvirt.gen_cdrom_image(connection, cdrom_img, vm_name, user_name, key_filename)
+        ip_netmask = "{0}/{1}".format(node.get('ip'), node.get('netmask'))
+        Libvirt.gen_cdrom_image(connection, cdrom_img, vm_name, user_name, key_filename, mac,
+                                ip_netmask)
         return node
 
 
@@ -567,7 +586,7 @@ class Server(object):
 
         for key, vfs in vnf["network_ports"].items():
             if key == "mgmt":
-                mgmtip = str(IPNetwork(vfs['cidr']).ip)
+                mgmt_cidr = IPNetwork(vfs['cidr'])
                 continue
 
             vf = ports[vfs[0]]
@@ -584,14 +603,15 @@ class Server(object):
             })
             index = index + 1
 
-        return mgmtip, interfaces
+        return mgmt_cidr, interfaces
 
     @classmethod
     def generate_vnf_instance(cls, flavor, ports, ip, key, vnf, mac):
-        mgmtip, interfaces = cls.build_vnf_interfaces(vnf, ports)
+        mgmt_cidr, interfaces = cls.build_vnf_interfaces(vnf, ports)
 
         result = {
-            "ip": mgmtip,
+            "ip": str(mgmt_cidr.ip),
+            "netmask": str(mgmt_cidr.netmask),
             "mac": mac,
             "host": ip,
             "user": flavor.get('user', 'root'),
index 5891f79..73311f0 100644 (file)
@@ -421,7 +421,8 @@ class OvsDpdkContext(base.Context):
                                                                   node,
                                                                   vm_name,
                                                                   self.name,
-                                                                  cdrom_img)
+                                                                  cdrom_img,
+                                                                  mac)
 
             # store vnf node details
             nodes.append(node)
index 8d410b2..f1b67a2 100644 (file)
@@ -253,7 +253,8 @@ class SriovContext(base.Context):
                                                                   node,
                                                                   vm_name,
                                                                   self.name,
-                                                                  cdrom_img)
+                                                                  cdrom_img,
+                                                                  mac)
 
             # store vnf node details
             nodes.append(node)
index 371e4ef..98d2b18 100644 (file)
@@ -205,10 +205,13 @@ class ModelLibvirtTestCase(unittest.TestCase):
         hostname = root.find('name').text
         meta_data = "/tmp/meta-data"
         user_data = "/tmp/user-data"
+        network_data = "/tmp/network-config"
         file_path = "/tmp/cdrom-0.img"
         key_filename = "id_rsa"
         pub_key_str = "KEY"
         user = 'root'
+        mac = "00:11:22:33:44:55"
+        ip = "1.1.1.7/24"
         user_config = ["    - name: {user_name}",
                        "      ssh_authorized_keys:",
                        "        - {pub_key_str}"]
@@ -218,7 +221,8 @@ class ModelLibvirtTestCase(unittest.TestCase):
                         create=True) as mock_file:
             with open(key_filename, "r") as h:
                 result = h.read()
-            model.Libvirt.gen_cdrom_image(self.mock_ssh, file_path, hostname, user, key_filename)
+            model.Libvirt.gen_cdrom_image(self.mock_ssh, file_path, hostname, user, key_filename,
+                                          mac, ip)
             mock_file.assert_called_with(".".join([key_filename, "pub"]), "r")
         self.assertEqual(result, pub_key_str)
 
@@ -226,9 +230,12 @@ class ModelLibvirtTestCase(unittest.TestCase):
             mock.call("touch %s" % meta_data),
             mock.call(model.USER_DATA_TEMPLATE.format(user_file=user_data, host=hostname,
                                                       user_config=user_conf)),
+            mock.call(model.NETWORK_DATA_TEMPLATE.format(network_file=network_data,
+                                                         mac_address=mac, ip_address=ip)),
             mock.call("genisoimage -output {0} -volid cidata"
-                      " -joliet -r {1} {2}".format(file_path, meta_data, user_data)),
-            mock.call("rm {0} {1}".format(meta_data, user_data))
+                      " -joliet -r {1} {2} {3}".format(file_path, meta_data, user_data,
+                                                       network_data)),
+            mock.call("rm {0} {1} {2}".format(meta_data, user_data, network_data))
         ])
 
     def test_create_snapshot_qemu(self):
@@ -273,16 +280,22 @@ class ModelLibvirtTestCase(unittest.TestCase):
 
     @mock.patch.object(model.Libvirt, 'gen_cdrom_image')
     def test_check_update_key(self, mock_gen_cdrom_image):
-        node = {'user': 'defuser', 'key_filename': '/home/ubuntu/id_rsa'}
+        node = {
+            'user': 'defuser',
+            'key_filename': '/home/ubuntu/id_rsa',
+            'ip': '1.1.1.7',
+            'netmask': '255.255.255.0'}
         cdrom_img = "/var/lib/libvirt/images/data.img"
         id_name = 'fake_name'
         key_filename = node.get('key_filename')
         root = ElementTree.fromstring(self.XML_STR)
         hostname = root.find('name').text
+        mac = "00:11:22:33:44:55"
+        ip = "{0}/{1}".format(node.get('ip'), node.get('netmask'))
         model.StandaloneContextHelper.check_update_key(self.mock_ssh, node, hostname, id_name,
-                                                       cdrom_img)
+                                                       cdrom_img, mac)
         mock_gen_cdrom_image.assert_called_once_with(self.mock_ssh, cdrom_img, hostname,
-                                                     node.get('user'), key_filename)
+                                                     node.get('user'), key_filename, mac, ip)
 
     @mock.patch.object(os, 'access', return_value=False)
     def test_create_snapshot_qemu_no_image_local(self, mock_os_access):
index 1a24075..6cc8b11 100644 (file)
@@ -418,7 +418,8 @@ class OvsDpdkContextTestCase(unittest.TestCase):
         self.ovs_dpdk.configure_nics_for_ovs_dpdk = mock.Mock(return_value="")
         self.ovs_dpdk._name_task_id = 'fake_name'
         xml_str = 'vm-0'
-        mock_build_xml.return_value = (xml_str, '00:00:00:00:00:01')
+        self.ovs_dpdk.mac = '00:00:00:00:00:01'
+        mock_build_xml.return_value = (xml_str, self.ovs_dpdk.mac)
         self.ovs_dpdk._enable_interfaces = mock.Mock(return_value=xml_str)
         vnf_instance = mock.Mock()
         vnf_instance_2 = mock.Mock()
@@ -439,7 +440,8 @@ class OvsDpdkContextTestCase(unittest.TestCase):
                                                       vnf_instance,
                                                       xml_str,
                                                       self.ovs_dpdk._name_task_id,
-                                                      self.ovs_dpdk.file_path)
+                                                      self.ovs_dpdk.file_path,
+                                                      self.ovs_dpdk.mac)
 
     @mock.patch.object(io, 'BytesIO')
     def test__check_hugepages(self, mock_bytesio):
index ae8e95f..316aca7 100644 (file)
@@ -301,8 +301,9 @@ class SriovContextTestCase(unittest.TestCase):
         self.sriov._name_task_id = 'fake_name'
         cfg = '/tmp/vm_sriov_0.xml'
         vm_name = 'vm-0'
+        mac = '00:00:00:00:00:01'
         xml_out = mock.Mock()
-        mock_build_vm_xml.return_value = (xml_out, '00:00:00:00:00:01')
+        mock_build_vm_xml.return_value = (xml_out, mac)
         mock_check_update_key.return_value = 'node_2'
         cdrom_img = '/var/lib/libvirt/images/cdrom-0.img'
 
@@ -314,7 +315,8 @@ class SriovContextTestCase(unittest.TestCase):
                 return_value='node_1')
             nodes_out = self.sriov.setup_sriov_context()
         mock_check_update_key.assert_called_once_with(connection, 'node_1', vm_name,
-                                                      self.sriov._name_task_id, cdrom_img)
+                                                      self.sriov._name_task_id, cdrom_img,
+                                                      mac)
         self.assertEqual(['node_2'], nodes_out)
         mock_vnf_node.generate_vnf_instance.assert_called_once_with(
             'flavor', 'networks', '1.2.3.4', 'vnf_0',