[Kimchi-devel] [PATCH V4 1/3] Implement backend code to edit MAC address of a guest

Jose Ricardo Ziviani joserz at linux.vnet.ibm.com
Thu May 28 13:51:19 UTC 2015


Signed-off-by: Jose Ricardo Ziviani <joserz at linux.vnet.ibm.com>
---
 src/kimchi/API.json          | 22 +++++++++----------
 src/kimchi/i18n.py           |  5 ++++-
 src/kimchi/model/vmifaces.py | 52 +++++++++++++++++++++++++++++---------------
 3 files changed, 50 insertions(+), 29 deletions(-)

diff --git a/src/kimchi/API.json b/src/kimchi/API.json
index a6330ae..b9a41eb 100644
--- a/src/kimchi/API.json
+++ b/src/kimchi/API.json
@@ -393,6 +393,12 @@
                     "type": "string",
                     "pattern": "^ne2k_pci|i82551|i82557b|i82559er|rtl8139|e1000|pcnet|virtio$",
                     "error": "KCHVMIF0006E"
+                },
+                "mac": {
+                    "description": "Network Interface Card MAC address",
+                    "type": "string",
+                    "pattern": "(^$)|^(([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$)",
+                    "error": "KCHVMIF0010E"
                 }
             }
         },
@@ -400,19 +406,13 @@
             "type": "object",
             "error": "KCHVMIF0008E",
             "properties": {
-                "network": {
-                    "description": "the name of one available network",
-                    "minLength": 1,
+                "mac": {
+                    "description": "Network Interface Card MAC address",
                     "type": "string",
-                    "error": "KCHVMIF0005E"
-                },
-                "model": {
-                    "description": "model of emulated network interface card",
-                    "enum": ["ne2k_pci", "i82551", "i82557b", "i82559er", "rtl8139", "e1000", "pcnet", "virtio", "spapr-vlan"],
-                    "error": "KCHVMIF0006E"
+                    "pattern": "^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$",
+                    "error": "KCHVMIF0010E"
                 }
-            },
-            "additionalProperties": false
+            }
         },
         "templates_create": {
             "type": "object",
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index 9f169ab..d5e93fa 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -126,7 +126,10 @@ messages = {
     "KCHVMIF0005E": _("Network name for virtual machine interface must be a string"),
     "KCHVMIF0006E": _("Invalid network model card specified for virtual machine interface"),
     "KCHVMIF0007E": _("Specify type and network to add a new virtual machine interface"),
-    "KCHVMIF0008E": _("Specify type and network to update a virtual machine interface"),
+    "KCHVMIF0008E": _("MAC Address must respect this format FF:FF:FF:FF:FF:FF"),
+    "KCHVMIF0009E": _("MAC Address %(mac)s already exists in virtual machine %(name)s"),
+    "KCHVMIF0010E": _("Invalid MAC Address"),
+    "KCHVMIF0011E": _("Cannot change MAC address of a running virtual machine"),
 
     "KCHTMPL0001E": _("Template %(name)s already exists"),
     "KCHTMPL0003E": _("Network '%(network)s' specified for template %(template)s does not exist"),
diff --git a/src/kimchi/model/vmifaces.py b/src/kimchi/model/vmifaces.py
index 8bf6b3d..50edde2 100644
--- a/src/kimchi/model/vmifaces.py
+++ b/src/kimchi/model/vmifaces.py
@@ -22,7 +22,8 @@ import random
 import libvirt
 from lxml import etree, objectify
 
-from kimchi.exception import InvalidParameter, MissingParameter, NotFoundError
+from kimchi.exception import InvalidParameter, MissingParameter
+from kimchi.exception import NotFoundError, InvalidOperation
 from kimchi.model.config import CapabilitiesModel
 from kimchi.model.vms import DOM_STATE_MAP, VMModel
 from kimchi.xmlutils.interface import get_iface_xml
@@ -57,10 +58,19 @@ class VMIfacesModel(object):
         macs = (iface.mac.get('address')
                 for iface in self.get_vmifaces(vm, self.conn))
 
-        while True:
-            params['mac'] = VMIfacesModel.random_mac()
-            if params['mac'] not in macs:
-                break
+        # user defined customized mac address
+        if 'mac' in params and params['mac']:
+            # make sure it is unique
+            if params['mac'] in macs:
+                raise InvalidParameter('KCHVMIF0009E',
+                                       {'name': vm, 'mac': params['mac']})
+
+        # otherwise choose a random mac address
+        else:
+            while True:
+                params['mac'] = VMIfacesModel.random_mac()
+                if params['mac'] not in macs:
+                    break
 
         dom = VMModel.get_vm(vm, self.conn)
 
@@ -147,22 +157,30 @@ class VMIfaceModel(object):
         if iface is None:
             raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac})
 
+        # mac address is a required parameter
+        if 'mac' not in params:
+            raise MissingParameter('KCHVMIF0008E')
+
+        # new mac address must be unique
+        if self._get_vmiface(vm, params['mac']) is not None:
+            raise InvalidParameter('KCHVMIF0009E',
+                                   {'name': vm, 'mac': params['mac']})
+
         flags = 0
         if dom.isPersistent():
             flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
-        if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
-            flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE
-
-        if iface.attrib['type'] == 'network' and 'network' in params:
-            iface.source.attrib['network'] = params['network']
-            xml = etree.tostring(iface)
 
-            dom.updateDeviceFlags(xml, flags=flags)
+        # cannot change mac address in a running system
+        if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
+            raise InvalidOperation('KCHVMIF0011E')
 
-        if 'model' in params:
-            iface.model.attrib["type"] = params['model']
-            xml = etree.tostring(iface)
+        # remove the current nic
+        xml = etree.tostring(iface)
+        dom.detachDeviceFlags(xml, flags=flags)
 
-            dom.updateDeviceFlags(xml, flags=flags)
+        # add the nic with the desired mac address
+        iface.mac.attrib['address'] = params['mac']
+        xml = etree.tostring(iface)
+        dom.attachDeviceFlags(xml, flags=flags)
 
-        return mac
+        return [vm, params['mac']]
-- 
1.9.1




More information about the Kimchi-devel mailing list