Revision ad4a9ae7 lib/config.py
b/lib/config.py | ||
---|---|---|
108 | 108 |
all_reserved.update(holder_reserved) |
109 | 109 |
return all_reserved |
110 | 110 |
|
111 |
def GetECReserved(self, ec_id): |
|
112 |
ec_reserved = set() |
|
113 |
if ec_id in self._ec_reserved: |
|
114 |
ec_reserved.update(self._ec_reserved[ec_id]) |
|
115 |
return ec_reserved |
|
116 |
|
|
117 |
|
|
111 | 118 |
def Generate(self, existing, generate_one_fn, ec_id): |
112 | 119 |
"""Generate a new resource of this type |
113 | 120 |
|
... | ... | |
178 | 185 |
self._temporary_macs = TemporaryReservationManager() |
179 | 186 |
self._temporary_secrets = TemporaryReservationManager() |
180 | 187 |
self._temporary_lvs = TemporaryReservationManager() |
188 |
self._temporary_ips = TemporaryReservationManager() |
|
181 | 189 |
self._all_rms = [self._temporary_ids, self._temporary_macs, |
182 |
self._temporary_secrets, self._temporary_lvs] |
|
190 |
self._temporary_secrets, self._temporary_lvs, |
|
191 |
self._temporary_ips] |
|
183 | 192 |
# Note: in order to prevent errors when resolving our name in |
184 | 193 |
# _DistributeConfig, we compute it here once and reuse it; it's |
185 | 194 |
# better to raise an error before starting to modify the config |
... | ... | |
291 | 300 |
else: |
292 | 301 |
self._temporary_macs.Reserve(ec_id, mac) |
293 | 302 |
|
303 |
def _UnlockedCommitTemporaryIps(self, ec_id): |
|
304 |
"""Commit all reserved IP address to their respective pools |
|
305 |
|
|
306 |
""" |
|
307 |
for action, address, net_uuid in self._temporary_ips.GetECReserved(ec_id): |
|
308 |
self._UnlockedCommitIp(action, net_uuid, address) |
|
309 |
|
|
310 |
def _UnlockedCommitIp(self, action, net_uuid, address): |
|
311 |
"""Commit a reserved IP address to an IP pool. |
|
312 |
|
|
313 |
The IP address is taken from the network's IP pool and marked as reserved. |
|
314 |
|
|
315 |
""" |
|
316 |
nobj = self._UnlockedGetNetwork(net_uuid) |
|
317 |
pool = network.AddressPool(nobj) |
|
318 |
if action == 'reserve': |
|
319 |
pool.Reserve(address) |
|
320 |
elif action == 'release': |
|
321 |
pool.Release(address) |
|
322 |
|
|
323 |
def _UnlockedReleaseIp(self, net_uuid, address, ec_id): |
|
324 |
"""Give a specific IP address back to an IP pool. |
|
325 |
|
|
326 |
The IP address is returned to the IP pool designated by pool_id and marked |
|
327 |
as reserved. |
|
328 |
|
|
329 |
""" |
|
330 |
nobj = self._UnlockedGetNetwork(net_uuid) |
|
331 |
pool = network.AddressPool(nobj) |
|
332 |
self._temporary_ips.Reserve(ec_id, ('release', address, net_uuid)) |
|
333 |
|
|
334 |
@locking.ssynchronized(_config_lock, shared=1) |
|
335 |
def ReleaseIp(self, network, address, ec_id): |
|
336 |
"""Give a specified IP address back to an IP pool. |
|
337 |
|
|
338 |
This is just a wrapper around _UnlockedReleaseIp. |
|
339 |
|
|
340 |
""" |
|
341 |
net_uuid = self._UnlockedLookupNetwork(network) |
|
342 |
if net_uuid: |
|
343 |
self._UnlockedReleaseIp(net_uuid, address, ec_id) |
|
344 |
|
|
345 |
@locking.ssynchronized(_config_lock, shared=1) |
|
346 |
def GenerateIp(self, net, ec_id): |
|
347 |
"""Find a free IPv4 address for an instance. |
|
348 |
|
|
349 |
""" |
|
350 |
net_uuid = self._UnlockedLookupNetwork(net) |
|
351 |
nobj = self._UnlockedGetNetwork(net_uuid) |
|
352 |
pool = network.AddressPool(nobj) |
|
353 |
gen_free = pool.GenerateFree() |
|
354 |
|
|
355 |
def gen_one(): |
|
356 |
try: |
|
357 |
ip = gen_free() |
|
358 |
except StopIteration: |
|
359 |
raise errors.ReservationError("Cannot generate IP. Network is full") |
|
360 |
return ("reserve", ip, net_uuid) |
|
361 |
|
|
362 |
_ ,address, _ = self._temporary_ips.Generate([], gen_one, ec_id) |
|
363 |
return address |
|
364 |
|
|
365 |
def _UnlockedReserveIp(self, net_uuid, address, ec_id): |
|
366 |
"""Reserve a given IPv4 address for use by an instance. |
|
367 |
|
|
368 |
""" |
|
369 |
nobj = self._UnlockedGetNetwork(net_uuid) |
|
370 |
pool = network.AddressPool(nobj) |
|
371 |
try: |
|
372 |
isreserved = pool.IsReserved(address) |
|
373 |
except errors.AddressPoolError: |
|
374 |
raise errors.ReservationError("IP address not in network") |
|
375 |
if isreserved: |
|
376 |
raise errors.ReservationError("IP address already in use") |
|
377 |
|
|
378 |
return self._temporary_ips.Reserve(ec_id, ('reserve', address, net_uuid)) |
|
379 |
|
|
380 |
|
|
381 |
@locking.ssynchronized(_config_lock, shared=1) |
|
382 |
def ReserveIp(self, net, address, ec_id): |
|
383 |
"""Reserve a given IPv4 address for use by an instance. |
|
384 |
|
|
385 |
""" |
|
386 |
net_uuid = self._UnlockedLookupNetwork(net) |
|
387 |
if net_uuid: |
|
388 |
return self._UnlockedReserveIp(net_uuid, address, ec_id) |
|
389 |
|
|
294 | 390 |
@locking.ssynchronized(_config_lock, shared=1) |
295 | 391 |
def ReserveLV(self, lv_name, ec_id): |
296 | 392 |
"""Reserve an VG/LV pair for an instance. |
... | ... | |
682 | 778 |
else: |
683 | 779 |
raise errors.ProgrammerError("NIC mode '%s' not handled" % nic_mode) |
684 | 780 |
|
685 |
_AddIpAddress("%s/%s" % (link, nic.ip),
|
|
781 |
_AddIpAddress("%s/%s/%s" % (link, nic.ip, nic.network),
|
|
686 | 782 |
"instance:%s/nic:%d" % (instance.name, idx)) |
687 | 783 |
|
688 | 784 |
for ip, owners in ips.items(): |
... | ... | |
2390 | 2486 |
del self._config_data.networks[network_uuid] |
2391 | 2487 |
self._config_data.cluster.serial_no += 1 |
2392 | 2488 |
self._WriteConfig() |
2489 |
|
|
2490 |
def _UnlockedGetGroupNetParams(self, net, node): |
|
2491 |
"""Get the netparams (mode, link) of a network. |
|
2492 |
|
|
2493 |
Get a network's netparams for a given node. |
|
2494 |
|
|
2495 |
@type net: string |
|
2496 |
@param net: network name |
|
2497 |
@type node: string |
|
2498 |
@param node: node name |
|
2499 |
@rtype: dict or None |
|
2500 |
@return: netparams |
|
2501 |
|
|
2502 |
""" |
|
2503 |
net_uuid = self._UnlockedLookupNetwork(net) |
|
2504 |
if net_uuid is None: |
|
2505 |
return None |
|
2506 |
|
|
2507 |
node_info = self._UnlockedGetNodeInfo(node) |
|
2508 |
nodegroup_info = self._UnlockedGetNodeGroup(node_info.group) |
|
2509 |
netparams = nodegroup_info.networks.get(net_uuid, None) |
|
2510 |
|
|
2511 |
return netparams |
|
2512 |
|
|
2513 |
@locking.ssynchronized(_config_lock, shared=1) |
|
2514 |
def GetGroupNetParams(self, net, node): |
|
2515 |
"""Locking wrapper of _UnlockedGetGroupNetParams() |
|
2516 |
|
|
2517 |
""" |
|
2518 |
return self._UnlockedGetGroupNetParams(net, node) |
|
2519 |
|
|
2520 |
|
|
2521 |
@locking.ssynchronized(_config_lock, shared=1) |
|
2522 |
def CheckIPInNodeGroup(self, ip, node): |
|
2523 |
"""Check for conflictig IP. |
|
2524 |
|
|
2525 |
@type ip: string |
|
2526 |
@param ip: ip address |
|
2527 |
@type node: string |
|
2528 |
@param node: node name |
|
2529 |
@rtype: (string, dict) or (None, None) |
|
2530 |
@return: (network name, netparams) |
|
2531 |
|
|
2532 |
""" |
|
2533 |
if ip is None: |
|
2534 |
return (None, None) |
|
2535 |
node_info = self._UnlockedGetNodeInfo(node) |
|
2536 |
nodegroup_info = self._UnlockedGetNodeGroup(node_info.group) |
|
2537 |
for net_uuid in nodegroup_info.networks.keys(): |
|
2538 |
net_info = self._UnlockedGetNetwork(net_uuid) |
|
2539 |
pool = network.AddressPool(net_info) |
|
2540 |
if pool._Contains(ip): |
|
2541 |
return (net_info.name, nodegroup_info.networks[net_uuid]) |
|
2542 |
|
|
2543 |
return (None, None) |
Also available in: Unified diff