X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/ad4a9ae704a012aa2440a851c159e3b09ae8a5c2..e81eef56ea737f109f7b80c1f3dbcd9376b3c224:/lib/config.py diff --git a/lib/config.py b/lib/config.py index b97414c..d2b9c56 100644 --- a/lib/config.py +++ b/lib/config.py @@ -109,12 +109,16 @@ class TemporaryReservationManager: 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 @@ -219,17 +223,6 @@ class ConfigWriter: """ return os.path.exists(pathutils.CLUSTER_CONF_FILE) - def _GenerateOneMAC(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 - @locking.ssynchronized(_config_lock, shared=1) def GetNdParams(self, node): """Get the node params populated with cluster defaults. @@ -276,15 +269,49 @@ class ConfigWriter: """ 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, 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) + 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) def ReserveMAC(self, mac, ec_id): @@ -315,9 +342,9 @@ class ConfigWriter: """ 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): @@ -327,18 +354,17 @@ class ConfigWriter: as reserved. """ - nobj = self._UnlockedGetNetwork(net_uuid) - pool = network.AddressPool(nobj) - 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, network, address, ec_id): + def ReleaseIp(self, net, address, ec_id): """Give a specified IP address back to an IP pool. This is just a wrapper around _UnlockedReleaseIp. """ - net_uuid = self._UnlockedLookupNetwork(network) + net_uuid = self._UnlockedLookupNetwork(net) if net_uuid: self._UnlockedReleaseIp(net_uuid, address, ec_id) @@ -357,9 +383,9 @@ class ConfigWriter: ip = gen_free() except StopIteration: 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) + _, address, _ = self._temporary_ips.Generate([], gen_one, ec_id) return address def _UnlockedReserveIp(self, net_uuid, address, ec_id): @@ -375,8 +401,9 @@ class ConfigWriter: 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): @@ -1359,6 +1386,7 @@ class ConfigWriter: self._config_data.instances[instance.name] = instance self._config_data.cluster.serial_no += 1 self._UnlockedReleaseDRBDMinors(instance.name) + self._UnlockedCommitTemporaryIps(ec_id) self._WriteConfig() def _EnsureUUID(self, item, ec_id): @@ -1420,6 +1448,15 @@ class ConfigWriter: if network_port is not None: self._config_data.cluster.tcpudp_port_pool.add(network_port) + instance = self._UnlockedGetInstanceInfo(instance_name) + + for nic in instance.nics: + if nic.network is not None and nic.ip is not None: + net_uuid = self._UnlockedLookupNetwork(nic.network) + if net_uuid: + # Return all IP addresses to the respective address pools + self._UnlockedCommitIp(constants.RELEASE_ACTION, net_uuid, nic.ip) + del self._config_data.instances[instance_name] self._config_data.cluster.serial_no += 1 self._WriteConfig() @@ -2292,7 +2329,7 @@ class ConfigWriter: return self._config_data.HasAnyDiskOfType(dev_type) @locking.ssynchronized(_config_lock) - def Update(self, target, feedback_fn): + def Update(self, target, feedback_fn, ec_id=None): """Notify function to be called after updates. This function must be called when an object (as returned by @@ -2339,6 +2376,10 @@ class ConfigWriter: if isinstance(target, objects.Instance): self._UnlockedReleaseDRBDMinors(target.name) + if ec_id is not None: + # Commit all ips reserved by OpInstanceSetParams and OpGroupSetParams + self._UnlockedCommitTemporaryIps(ec_id) + self._WriteConfig(feedback_fn=feedback_fn) @locking.ssynchronized(_config_lock) @@ -2378,8 +2419,8 @@ class ConfigWriter: """Get a list of network names """ - names = [network.name - for network in self._config_data.networks.values()] + names = [net.name + for net in self._config_data.networks.values()] return names def _UnlockedGetNetwork(self, uuid): @@ -2517,7 +2558,6 @@ class ConfigWriter: """ return self._UnlockedGetGroupNetParams(net, node) - @locking.ssynchronized(_config_lock, shared=1) def CheckIPInNodeGroup(self, ip, node): """Check for conflictig IP. @@ -2537,7 +2577,7 @@ class ConfigWriter: for net_uuid in nodegroup_info.networks.keys(): net_info = self._UnlockedGetNetwork(net_uuid) pool = network.AddressPool(net_info) - if pool._Contains(ip): + if pool.Contains(ip): return (net_info.name, nodegroup_info.networks[net_uuid]) return (None, None)