Use network's mac prefix
authorDimitris Aragiorgis <dimara@grnet.gr>
Tue, 5 Jun 2012 23:03:08 +0000 (02:03 +0300)
committerIustin Pop <iustin@google.com>
Tue, 20 Nov 2012 17:51:19 +0000 (18:51 +0100)
Modify existing GenerateMAC so that it takes network as an argument.

Substitute _GenerateOneMAC with a decorator _GenerateMACPrefix that
chooses the prefix (network's or cluster's) and wraps
_GenerateMACSuffix that generates the three remaining bytes.

Check mac prefix validity when adding/modifing a network.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Iustin Pop <iustin@google.com>

lib/cmdlib.py
lib/config.py

index 690053a..02f8ebd 100644 (file)
@@ -10120,7 +10120,7 @@ class LUInstanceCreate(LogicalUnit):
     # creation job will fail.
     for nic in self.nics:
       if nic.mac in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
-        nic.mac = self.cfg.GenerateMAC(self.proc.GetECId())
+        nic.mac = self.cfg.GenerateMAC(nic.network, self.proc.GetECId())
 
     #### allocator run
 
@@ -12846,7 +12846,7 @@ class LUInstanceSetParams(LogicalUnit):
       elif mac in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
         # otherwise generate the MAC address
         params[constants.INIC_MAC] = \
-          self.cfg.GenerateMAC(self.proc.GetECId())
+          self.cfg.GenerateMAC(new_net, self.proc.GetECId())
       else:
         # or validate/reserve the current one
         try:
@@ -12867,7 +12867,7 @@ class LUInstanceSetParams(LogicalUnit):
       old_prefix = get_net_prefix(old_net)
       if old_prefix != new_prefix:
         params[constants.INIC_MAC] = \
-          self.cfg.GenerateMAC(self.proc.GetECId())
+          self.cfg.GenerateMAC(new_net, self.proc.GetECId())
 
     #if there is a change in nic-network configuration
     new_ip = params.get(constants.INIC_IP, old_ip)
@@ -15482,6 +15482,8 @@ class LUNetworkAdd(LogicalUnit):
       raise errors.OpPrereqError("Network '%s' already defined" %
                                  self.op.network, errors.ECODE_EXISTS)
 
+    if self.op.mac_prefix:
+      utils.NormalizeAndValidateMac(self.op.mac_prefix+":00:00:00")
 
   def BuildHooksEnv(self):
     """Build hooks env.
@@ -15670,6 +15672,7 @@ class LUNetworkSetParams(LogicalUnit):
       if self.op.mac_prefix == constants.VALUE_NONE:
         self.mac_prefix = None
       else:
+        utils.NormalizeAndValidateMac(self.op.mac_prefix+":00:00:00")
         self.mac_prefix = self.op.mac_prefix
 
     if self.op.gateway6:
index 2a70abf..a98779c 100644 (file)
@@ -39,6 +39,7 @@ import random
 import logging
 import time
 import itertools
+from functools import wraps
 
 from ganeti import errors
 from ganeti import locking
@@ -219,16 +220,30 @@ class ConfigWriter:
     """
     return os.path.exists(pathutils.CLUSTER_CONF_FILE)
 
-  def _GenerateOneMAC(self):
+  def _GenerateMACPrefix(self, net=None):
+    def _get_mac_prefix(view_func):
+      def _decorator(*args, **kwargs):
+        prefix = self._config_data.cluster.mac_prefix
+        if net:
+          net_uuid = self._UnlockedLookupNetwork(net)
+          if net_uuid:
+            nobj = self._UnlockedGetNetwork(net_uuid)
+            if nobj.mac_prefix:
+              prefix = nobj.mac_prefix
+        suffix = view_func(*args, **kwargs)
+        return prefix+':'+suffix
+      return wraps(view_func)(_decorator)
+    return _get_mac_prefix
+
+  def _GenerateMACSuffix(self):
     """Generate one mac address
 
     """
-    prefix = self._config_data.cluster.mac_prefix
     byte1 = random.randrange(0, 256)
     byte2 = random.randrange(0, 256)
     byte3 = random.randrange(0, 256)
-    mac = "%s:%02x:%02x:%02x" % (prefix, byte1, byte2, byte3)
-    return mac
+    suffix = "%02x:%02x:%02x" % (byte1, byte2, byte3)
+    return suffix
 
   @locking.ssynchronized(_config_lock, shared=1)
   def GetNdParams(self, node):
@@ -277,14 +292,15 @@ class ConfigWriter:
     return self._config_data.cluster.SimpleFillDP(group.diskparams)
 
   @locking.ssynchronized(_config_lock, shared=1)
-  def GenerateMAC(self, ec_id):
+  def GenerateMAC(self, net, ec_id):
     """Generate a MAC for an instance.
 
     This should check the current instances for duplicates.
 
     """
     existing = self._AllMACs()
-    return self._temporary_ids.Generate(existing, self._GenerateOneMAC, ec_id)
+    gen_mac = self._GenerateMACPrefix(net)(self._GenerateMACSuffix)
+    return self._temporary_ids.Generate(existing, gen_mac, ec_id)
 
   @locking.ssynchronized(_config_lock, shared=1)
   def ReserveMAC(self, mac, ec_id):