import logging
import time
import itertools
-from functools import wraps
from ganeti import errors
from ganeti import locking
return all_reserved
def GetECReserved(self, ec_id):
+ """ Used when you want to retrieve all reservations for a specific
+ execution context. E.g when commiting reserved IPs for a specific
+ network.
+
+ """
ec_reserved = set()
if ec_id in self._ec_reserved:
ec_reserved.update(self._ec_reserved[ec_id])
return ec_reserved
-
def Generate(self, existing, generate_one_fn, ec_id):
"""Generate a new resource of this type
return result
-def _GenerateMACSuffix():
- """Generate one mac address
-
- """
- byte1 = random.randrange(0, 256)
- byte2 = random.randrange(0, 256)
- byte3 = random.randrange(0, 256)
- suffix = "%02x:%02x:%02x" % (byte1, byte2, byte3)
- return suffix
-
class ConfigWriter:
"""The interface to the cluster configuration.
"""
return os.path.exists(pathutils.CLUSTER_CONF_FILE)
- 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
-
@locking.ssynchronized(_config_lock, shared=1)
def GetNdParams(self, node):
"""Get the node params populated with cluster defaults.
"""
return self._config_data.cluster.SimpleFillDP(group.diskparams)
+ def _UnlockedGetNetworkMACPrefix(self, net):
+ """Return the network mac prefix if it exists or the cluster level default.
+
+ """
+ prefix = None
+ if net:
+ net_uuid = self._UnlockedLookupNetwork(net)
+ if net_uuid:
+ nobj = self._UnlockedGetNetwork(net_uuid)
+ if nobj.mac_prefix:
+ prefix = nobj.mac_prefix
+
+ return prefix
+
+ def _GenerateOneMAC(self, prefix=None):
+ """Return a function that randomly generates a MAC suffic
+ and appends it to the given prefix. If prefix is not given get
+ the cluster level default.
+
+ """
+ if not prefix:
+ prefix = self._config_data.cluster.mac_prefix
+
+ def GenMac():
+ 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
+
+ return GenMac
+
@locking.ssynchronized(_config_lock, shared=1)
def GenerateMAC(self, net, ec_id):
"""Generate a MAC for an instance.
"""
existing = self._AllMACs()
- gen_mac = self._GenerateMACPrefix(net)(_GenerateMACSuffix)
+ prefix = self._UnlockedGetNetworkMACPrefix(net)
+ gen_mac = self._GenerateOneMAC(prefix)
return self._temporary_ids.Generate(existing, gen_mac, ec_id)
@locking.ssynchronized(_config_lock, shared=1)
"""
nobj = self._UnlockedGetNetwork(net_uuid)
pool = network.AddressPool(nobj)
- if action == 'reserve':
+ if action == constants.RESERVE_ACTION:
pool.Reserve(address)
- elif action == 'release':
+ elif action == constants.RELEASE_ACTION:
pool.Release(address)
def _UnlockedReleaseIp(self, net_uuid, address, ec_id):
as reserved.
"""
- self._temporary_ips.Reserve(ec_id, ('release', address, net_uuid))
+ self._temporary_ips.Reserve(ec_id,
+ (constants.RELEASE_ACTION, address, net_uuid))
@locking.ssynchronized(_config_lock, shared=1)
def ReleaseIp(self, net, address, ec_id):
net_uuid = self._UnlockedLookupNetwork(net)
nobj = self._UnlockedGetNetwork(net_uuid)
pool = network.AddressPool(nobj)
- gen_free = pool.GenerateFree()
def gen_one():
try:
- ip = gen_free()
- except StopIteration:
+ ip = pool.GenerateFree()
+ except errors.AddressPoolError:
raise errors.ReservationError("Cannot generate IP. Network is full")
- return ("reserve", ip, net_uuid)
+ return (constants.RESERVE_ACTION, ip, net_uuid)
_, address, _ = self._temporary_ips.Generate([], gen_one, ec_id)
return address
if isreserved:
raise errors.ReservationError("IP address already in use")
- return self._temporary_ips.Reserve(ec_id, ('reserve', address, net_uuid))
-
+ return self._temporary_ips.Reserve(ec_id,
+ (constants.RESERVE_ACTION,
+ address, net_uuid))
@locking.ssynchronized(_config_lock, shared=1)
def ReserveIp(self, net, address, ec_id):
net_uuid = self._UnlockedLookupNetwork(nic.network)
if net_uuid:
# Return all IP addresses to the respective address pools
- self._UnlockedCommitIp('release', net_uuid, nic.ip)
-
+ self._UnlockedCommitIp(constants.RELEASE_ACTION, net_uuid, nic.ip)
del self._config_data.instances[instance_name]
self._config_data.cluster.serial_no += 1
@locking.ssynchronized(_config_lock, shared=1)
def GetAllNetworksInfo(self):
- """Get the configuration of all networks
+ """Get configuration info of all the networks.
"""
return dict(self._config_data.networks)
"""
return self._UnlockedGetGroupNetParams(net, node)
-
@locking.ssynchronized(_config_lock, shared=1)
def CheckIPInNodeGroup(self, ip, node):
- """Check for conflictig IP.
+ """Check IP uniqueness in nodegroup.
+
+ Check networks that are connected in the node's node group
+ if ip is contained in any of them. Used when creating/adding
+ a NIC to ensure uniqueness among nodegroups.
@type ip: string
@param ip: ip address