Revision c01a7953
b/lib/cmdlib/instance.py | ||
---|---|---|
834 | 834 |
|
835 | 835 |
""" |
836 | 836 |
self._CalculateFileStorageDir() |
837 |
ec_id = self.proc.GetECId() |
|
837 | 838 |
|
838 | 839 |
if self.op.mode == constants.INSTANCE_IMPORT: |
839 | 840 |
export_info = self._ReadExportInfo() |
... | ... | |
886 | 887 |
self._RevertToDefaults(cluster) |
887 | 888 |
|
888 | 889 |
# NIC buildup |
889 |
self.nics = _ComputeNics(self.op, cluster, self.check_ip, self.cfg, |
|
890 |
self.proc.GetECId()) |
|
890 |
self.nics = _ComputeNics(self.op, cluster, self.check_ip, self.cfg, ec_id) |
|
891 | 891 |
|
892 | 892 |
# disk checks/pre-build |
893 | 893 |
default_vg = self.cfg.GetVGName() |
... | ... | |
932 | 932 |
# creation job will fail. |
933 | 933 |
for nic in self.nics: |
934 | 934 |
if nic.mac in (constants.VALUE_AUTO, constants.VALUE_GENERATE): |
935 |
nic.mac = self.cfg.GenerateMAC(nic.network, self.proc.GetECId())
|
|
935 |
nic.mac = self.cfg.GenerateMAC(nic.network, ec_id)
|
|
936 | 936 |
|
937 | 937 |
#### allocator run |
938 | 938 |
|
... | ... | |
986 | 986 |
if nic.ip is not None: |
987 | 987 |
if nic.ip.lower() == constants.NIC_IP_POOL: |
988 | 988 |
try: |
989 |
nic.ip = self.cfg.GenerateIp(net_uuid, self.proc.GetECId())
|
|
989 |
nic.ip = self.cfg.GenerateIp(net_uuid, ec_id)
|
|
990 | 990 |
except errors.ReservationError: |
991 | 991 |
raise errors.OpPrereqError("Unable to get a free IP for NIC %d" |
992 | 992 |
" from the address pool" % idx, |
... | ... | |
994 | 994 |
self.LogInfo("Chose IP %s from network %s", nic.ip, nobj.name) |
995 | 995 |
else: |
996 | 996 |
try: |
997 |
self.cfg.ReserveIp(net_uuid, nic.ip, self.proc.GetECId())
|
|
997 |
self.cfg.ReserveIp(net_uuid, nic.ip, ec_id)
|
|
998 | 998 |
except errors.ReservationError: |
999 | 999 |
raise errors.OpPrereqError("IP address %s already in use" |
1000 | 1000 |
" or does not belong to network %s" % |
... | ... | |
2507 | 2507 |
if new_ip.lower() == constants.NIC_IP_POOL: |
2508 | 2508 |
if new_net_uuid: |
2509 | 2509 |
try: |
2510 |
new_ip = self.cfg.GenerateIp(new_net_uuid, self.proc.GetECId())
|
|
2510 |
new_ip = self.cfg.GenerateIp(new_net_uuid, ec_id)
|
|
2511 | 2511 |
except errors.ReservationError: |
2512 | 2512 |
raise errors.OpPrereqError("Unable to get a free IP" |
2513 | 2513 |
" from the address pool", |
2514 | 2514 |
errors.ECODE_STATE) |
2515 | 2515 |
self.LogInfo("Chose IP %s from network %s", |
2516 |
new_ip, |
|
2517 |
new_net_obj.name) |
|
2516 |
new_ip, new_net_obj.name) |
|
2518 | 2517 |
params[constants.INIC_IP] = new_ip |
2519 | 2518 |
else: |
2520 | 2519 |
raise errors.OpPrereqError("ip=pool, but no network found", |
... | ... | |
2522 | 2521 |
# Reserve new IP if in the new network if any |
2523 | 2522 |
elif new_net_uuid: |
2524 | 2523 |
try: |
2525 |
self.cfg.ReserveIp(new_net_uuid, new_ip, self.proc.GetECId())
|
|
2524 |
self.cfg.ReserveIp(new_net_uuid, new_ip, ec_id)
|
|
2526 | 2525 |
self.LogInfo("Reserving IP %s in network %s", |
2527 | 2526 |
new_ip, new_net_obj.name) |
2528 | 2527 |
except errors.ReservationError: |
... | ... | |
2536 | 2535 |
# release old IP if old network is not None |
2537 | 2536 |
if old_ip and old_net_uuid: |
2538 | 2537 |
try: |
2539 |
self.cfg.ReleaseIp(old_net_uuid, old_ip, self.proc.GetECId())
|
|
2538 |
self.cfg.ReleaseIp(old_net_uuid, old_ip, False, ec_id)
|
|
2540 | 2539 |
except errors.AddressPoolError: |
2541 | 2540 |
logging.warning("Release IP %s not contained in network %s", |
2542 | 2541 |
old_ip, old_net_obj.name) |
... | ... | |
2914 | 2913 |
ip = params.ip |
2915 | 2914 |
net = params.network |
2916 | 2915 |
if net is not None and ip is not None: |
2917 |
self.cfg.ReleaseIp(net, ip, self.proc.GetECId()) |
|
2916 |
self.cfg.ReleaseIp(net, ip, False, self.proc.GetECId())
|
|
2918 | 2917 |
|
2919 | 2918 |
# Verify NIC changes (operating on copy) |
2920 | 2919 |
nics = instance.nics[:] |
b/lib/cmdlib/network.py | ||
---|---|---|
128 | 128 |
for tag in self.op.tags: |
129 | 129 |
objects.TaggableObject.ValidateTag(tag) |
130 | 130 |
|
131 |
self.nobj = objects.Network(name=self.op.network_name, |
|
132 |
network=self.op.network, |
|
133 |
gateway=self.op.gateway, |
|
134 |
network6=self.op.network6, |
|
135 |
gateway6=self.op.gateway6, |
|
136 |
mac_prefix=self.op.mac_prefix, |
|
137 |
uuid=self.network_uuid) |
|
138 |
|
|
139 |
# Initialize the associated address pool |
|
140 |
try: |
|
141 |
self.pool = network.AddressPool.InitializeNetwork(self.nobj) |
|
142 |
except errors.AddressPoolError, err: |
|
143 |
raise errors.OpPrereqError("Cannot create IP address pool for network" |
|
144 |
" '%s': %s" % (self.op.network_name, err)) |
|
145 |
|
|
131 | 146 |
def BuildHooksEnv(self): |
132 | 147 |
"""Build hooks env. |
133 | 148 |
|
... | ... | |
147 | 162 |
"""Add the ip pool to the cluster. |
148 | 163 |
|
149 | 164 |
""" |
150 |
nobj = objects.Network(name=self.op.network_name, |
|
151 |
network=self.op.network, |
|
152 |
gateway=self.op.gateway, |
|
153 |
network6=self.op.network6, |
|
154 |
gateway6=self.op.gateway6, |
|
155 |
mac_prefix=self.op.mac_prefix, |
|
156 |
uuid=self.network_uuid) |
|
157 |
# Initialize the associated address pool |
|
158 |
try: |
|
159 |
pool = network.AddressPool.InitializeNetwork(nobj) |
|
160 |
except errors.AddressPoolError, err: |
|
161 |
raise errors.OpExecError("Cannot create IP address pool for network" |
|
162 |
" '%s': %s" % (self.op.network_name, err)) |
|
163 |
|
|
164 | 165 |
# Check if we need to reserve the nodes and the cluster master IP |
165 | 166 |
# These may not be allocated to any instances in routed mode, as |
166 | 167 |
# they wouldn't function anyway. |
... | ... | |
168 | 169 |
for node in self.cfg.GetAllNodesInfo().values(): |
169 | 170 |
for ip in [node.primary_ip, node.secondary_ip]: |
170 | 171 |
try: |
171 |
if pool.Contains(ip): |
|
172 |
pool.Reserve(ip)
|
|
172 |
if self.pool.Contains(ip):
|
|
173 |
self.pool.Reserve(ip, True)
|
|
173 | 174 |
self.LogInfo("Reserved IP address of node '%s' (%s)", |
174 | 175 |
node.name, ip) |
175 | 176 |
except errors.AddressPoolError, err: |
... | ... | |
178 | 179 |
|
179 | 180 |
master_ip = self.cfg.GetClusterInfo().master_ip |
180 | 181 |
try: |
181 |
if pool.Contains(master_ip): |
|
182 |
pool.Reserve(master_ip)
|
|
182 |
if self.pool.Contains(master_ip):
|
|
183 |
self.pool.Reserve(master_ip, True)
|
|
183 | 184 |
self.LogInfo("Reserved cluster master IP address (%s)", master_ip) |
184 | 185 |
except errors.AddressPoolError, err: |
185 | 186 |
self.LogWarning("Cannot reserve cluster master IP address (%s): %s", |
... | ... | |
188 | 189 |
if self.op.add_reserved_ips: |
189 | 190 |
for ip in self.op.add_reserved_ips: |
190 | 191 |
try: |
191 |
pool.Reserve(ip, external=True) |
|
192 |
self.pool.Reserve(ip, external=True)
|
|
192 | 193 |
except errors.AddressPoolError, err: |
193 | 194 |
raise errors.OpExecError("Cannot reserve IP address '%s': %s" % |
194 | 195 |
(ip, err)) |
195 | 196 |
|
196 | 197 |
if self.op.tags: |
197 | 198 |
for tag in self.op.tags: |
198 |
nobj.AddTag(tag) |
|
199 |
self.nobj.AddTag(tag)
|
|
199 | 200 |
|
200 |
self.cfg.AddNetwork(nobj, self.proc.GetECId(), check_uuid=False) |
|
201 |
self.cfg.AddNetwork(self.nobj, self.proc.GetECId(), check_uuid=False)
|
|
201 | 202 |
del self.remove_locks[locking.LEVEL_NETWORK] |
202 | 203 |
|
203 | 204 |
|
... | ... | |
300 | 301 |
self.gateway = None |
301 | 302 |
else: |
302 | 303 |
self.gateway = self.op.gateway |
303 |
if self.pool.IsReserved(self.gateway): |
|
304 |
raise errors.OpPrereqError("Gateway IP address '%s' is already" |
|
305 |
" reserved" % self.gateway, |
|
306 |
errors.ECODE_STATE) |
|
307 | 304 |
|
308 | 305 |
if self.op.mac_prefix: |
309 | 306 |
if self.op.mac_prefix == constants.VALUE_NONE: |
... | ... | |
352 | 349 |
""" |
353 | 350 |
#TODO: reserve/release via temporary reservation manager |
354 | 351 |
# extend cfg.ReserveIp/ReleaseIp with the external flag |
352 |
ec_id = self.proc.GetECId() |
|
355 | 353 |
if self.op.gateway: |
356 | 354 |
if self.gateway == self.network.gateway: |
357 | 355 |
self.LogWarning("Gateway is already %s", self.gateway) |
358 | 356 |
else: |
359 | 357 |
if self.gateway: |
360 |
self.pool.Reserve(self.gateway, external=True)
|
|
358 |
self.cfg.ReserveIp(self.network_uuid, self.gateway, True, ec_id)
|
|
361 | 359 |
if self.network.gateway: |
362 |
self.pool.Release(self.network.gateway, external=True)
|
|
360 |
self.cfg.ReleaseIp(self.network_uuid, self.network.gateway, True, ec_id)
|
|
363 | 361 |
self.network.gateway = self.gateway |
364 | 362 |
|
365 | 363 |
if self.op.add_reserved_ips: |
366 | 364 |
for ip in self.op.add_reserved_ips: |
367 |
try: |
|
368 |
if self.pool.IsReserved(ip): |
|
369 |
self.LogWarning("IP address %s is already reserved", ip) |
|
370 |
else: |
|
371 |
self.pool.Reserve(ip, external=True) |
|
372 |
except errors.AddressPoolError, err: |
|
373 |
self.LogWarning("Cannot reserve IP address %s: %s", ip, err) |
|
365 |
self.cfg.ReserveIp(self.network_uuid, ip, True, ec_id) |
|
374 | 366 |
|
375 | 367 |
if self.op.remove_reserved_ips: |
376 | 368 |
for ip in self.op.remove_reserved_ips: |
377 | 369 |
if ip == self.network.gateway: |
378 | 370 |
self.LogWarning("Cannot unreserve Gateway's IP") |
379 | 371 |
continue |
380 |
try: |
|
381 |
if not self.pool.IsReserved(ip): |
|
382 |
self.LogWarning("IP address %s is already unreserved", ip) |
|
383 |
else: |
|
384 |
self.pool.Release(ip, external=True) |
|
385 |
except errors.AddressPoolError, err: |
|
386 |
self.LogWarning("Cannot release IP address %s: %s", ip, err) |
|
372 |
self.cfg.ReleaseIp(self.network_uuid, ip, True, ec_id) |
|
387 | 373 |
|
388 | 374 |
if self.op.mac_prefix: |
389 | 375 |
self.network.mac_prefix = self.mac_prefix |
b/lib/config.py | ||
---|---|---|
330 | 330 |
"""Commit all reserved IP address to their respective pools |
331 | 331 |
|
332 | 332 |
""" |
333 |
for action, address, net_uuid in self._temporary_ips.GetECReserved(ec_id): |
|
334 |
self._UnlockedCommitIp(action, net_uuid, address) |
|
333 |
for action, address, net_uuid, external in \ |
|
334 |
self._temporary_ips.GetECReserved(ec_id): |
|
335 |
self._UnlockedCommitIp(action, net_uuid, address, external) |
|
335 | 336 |
|
336 |
def _UnlockedCommitIp(self, action, net_uuid, address): |
|
337 |
def _UnlockedCommitIp(self, action, net_uuid, address, external):
|
|
337 | 338 |
"""Commit a reserved IP address to an IP pool. |
338 | 339 |
|
339 | 340 |
The IP address is taken from the network's IP pool and marked as reserved. |
... | ... | |
342 | 343 |
nobj = self._UnlockedGetNetwork(net_uuid) |
343 | 344 |
pool = network.AddressPool(nobj) |
344 | 345 |
if action == constants.RESERVE_ACTION: |
345 |
pool.Reserve(address) |
|
346 |
pool.Reserve(address, external)
|
|
346 | 347 |
elif action == constants.RELEASE_ACTION: |
347 |
pool.Release(address) |
|
348 |
pool.Release(address, external)
|
|
348 | 349 |
|
349 |
def _UnlockedReleaseIp(self, net_uuid, address, ec_id): |
|
350 |
def _UnlockedReleaseIp(self, net_uuid, address, external, ec_id):
|
|
350 | 351 |
"""Give a specific IP address back to an IP pool. |
351 | 352 |
|
352 | 353 |
The IP address is returned to the IP pool designated by pool_id and marked |
... | ... | |
354 | 355 |
|
355 | 356 |
""" |
356 | 357 |
self._temporary_ips.Reserve(ec_id, |
357 |
(constants.RELEASE_ACTION, address, net_uuid)) |
|
358 |
(constants.RELEASE_ACTION, |
|
359 |
address, net_uuid, external)) |
|
358 | 360 |
|
359 | 361 |
@locking.ssynchronized(_config_lock, shared=1) |
360 |
def ReleaseIp(self, net_uuid, address, ec_id): |
|
362 |
def ReleaseIp(self, net_uuid, address, external, ec_id):
|
|
361 | 363 |
"""Give a specified IP address back to an IP pool. |
362 | 364 |
|
363 | 365 |
This is just a wrapper around _UnlockedReleaseIp. |
364 | 366 |
|
365 | 367 |
""" |
366 | 368 |
if net_uuid: |
367 |
self._UnlockedReleaseIp(net_uuid, address, ec_id) |
|
369 |
self._UnlockedReleaseIp(net_uuid, address, external, ec_id)
|
|
368 | 370 |
|
369 | 371 |
@locking.ssynchronized(_config_lock, shared=1) |
370 | 372 |
def GenerateIp(self, net_uuid, ec_id): |
... | ... | |
378 | 380 |
try: |
379 | 381 |
ip = pool.GenerateFree() |
380 | 382 |
except errors.AddressPoolError: |
381 |
raise errors.ReservationError("Cannot generate IP. Network is full") |
|
382 |
return (constants.RESERVE_ACTION, ip, net_uuid) |
|
383 |
raise errors.OpPrereqError("Cannot generate IP." |
|
384 |
" Network '%s' is full." % nobj.name, |
|
385 |
errors.ECODE_STATE) |
|
386 |
return (constants.RESERVE_ACTION, ip, net_uuid, False) |
|
383 | 387 |
|
384 |
_, address, _ = self._temporary_ips.Generate([], gen_one, ec_id) |
|
388 |
_, address, _, _ = self._temporary_ips.Generate([], gen_one, ec_id)
|
|
385 | 389 |
return address |
386 | 390 |
|
387 |
def _UnlockedReserveIp(self, net_uuid, address, ec_id): |
|
391 |
def _UnlockedReserveIp(self, net_uuid, address, external, ec_id):
|
|
388 | 392 |
"""Reserve a given IPv4 address for use by an instance. |
389 | 393 |
|
390 | 394 |
""" |
391 | 395 |
nobj = self._UnlockedGetNetwork(net_uuid) |
392 | 396 |
pool = network.AddressPool(nobj) |
393 |
try: |
|
394 |
isreserved = pool.IsReserved(address) |
|
395 |
except errors.AddressPoolError: |
|
396 |
raise errors.ReservationError("IP address not in network") |
|
397 |
if isreserved: |
|
398 |
raise errors.ReservationError("IP address already in use") |
|
397 |
if pool.IsReserved(address): |
|
398 |
raise errors.OpPrereqError("IP address '%s' already in use." % |
|
399 |
address, errors.ECODE_EXISTS) |
|
399 | 400 |
|
400 | 401 |
return self._temporary_ips.Reserve(ec_id, |
401 | 402 |
(constants.RESERVE_ACTION, |
402 |
address, net_uuid)) |
|
403 |
address, net_uuid, external))
|
|
403 | 404 |
|
404 | 405 |
@locking.ssynchronized(_config_lock, shared=1) |
405 |
def ReserveIp(self, net_uuid, address, ec_id): |
|
406 |
def ReserveIp(self, net_uuid, address, external, ec_id):
|
|
406 | 407 |
"""Reserve a given IPv4 address for use by an instance. |
407 | 408 |
|
408 | 409 |
""" |
409 | 410 |
if net_uuid: |
410 |
return self._UnlockedReserveIp(net_uuid, address, ec_id) |
|
411 |
return self._UnlockedReserveIp(net_uuid, address, external, ec_id)
|
|
411 | 412 |
|
412 | 413 |
@locking.ssynchronized(_config_lock, shared=1) |
413 | 414 |
def ReserveLV(self, lv_name, ec_id): |
... | ... | |
1487 | 1488 |
for nic in instance.nics: |
1488 | 1489 |
if nic.network and nic.ip: |
1489 | 1490 |
# Return all IP addresses to the respective address pools |
1490 |
self._UnlockedCommitIp(constants.RELEASE_ACTION, nic.network, nic.ip) |
|
1491 |
self._UnlockedCommitIp(constants.RELEASE_ACTION, |
|
1492 |
nic.network, nic.ip, False) |
|
1491 | 1493 |
|
1492 | 1494 |
del self._config_data.instances[instance_name] |
1493 | 1495 |
self._config_data.cluster.serial_no += 1 |
... | ... | |
2438 | 2440 |
if isinstance(target, objects.Instance): |
2439 | 2441 |
self._UnlockedReleaseDRBDMinors(target.name) |
2440 | 2442 |
|
2441 |
if ec_id is not None: |
|
2442 |
# Commit all ips reserved by OpInstanceSetParams and OpGroupSetParams |
|
2443 |
self._UnlockedCommitTemporaryIps(ec_id) |
|
2443 |
self._UnlockedCommitTemporaryIps(ec_id) |
|
2444 | 2444 |
|
2445 | 2445 |
self._WriteConfig(feedback_fn=feedback_fn) |
2446 | 2446 |
|
Also available in: Unified diff