Revision 62a7762b

b/lib/config.py
49 49
from ganeti import uidpool
50 50
from ganeti import netutils
51 51
from ganeti import runtime
52
from ganeti import ippool
52 53

  
53 54

  
54 55
_config_lock = locking.SharedLock("ConfigWriter")
......
148 149
    self._temporary_macs = TemporaryReservationManager()
149 150
    self._temporary_secrets = TemporaryReservationManager()
150 151
    self._temporary_lvs = TemporaryReservationManager()
152
    self._temporary_ips = TemporaryReservationManager()
151 153
    self._all_rms = [self._temporary_ids, self._temporary_macs,
152
                     self._temporary_secrets, self._temporary_lvs]
154
                     self._temporary_secrets, self._temporary_lvs,
155
                     self._temporary_ips]
153 156
    # Note: in order to prevent errors when resolving our name in
154 157
    # _DistributeConfig, we compute it here once and reuse it; it's
155 158
    # better to raise an error before starting to modify the config
......
214 217
    else:
215 218
      self._temporary_macs.Reserve(ec_id, mac)
216 219

  
220
  def _UnlockedCommitIp(self, link, address):
221
    """Commit a reserved IP address to an IP pool.
222

  
223
    The IP address is taken from the IP pool designated by link and marked
224
    as reserved.
225

  
226
    """
227
    if link is None:
228
      nicparams = self._config_data.cluster.nicparams[constants.VALUE_DEFAULT]
229
      link = nicparams[constants.NIC_LINK]
230

  
231
    if link not in self._config_data.cluster.networks or\
232
      "4" not in self._config_data.cluster.networks[link]:
233
      return False
234

  
235
    netdict = self._config_data.cluster.networks[link]["4"]
236
    network = ippool.IPv4Network.fromdict(netdict)
237
    try:
238
      addr = network.reserve(address)
239
    except ippool.IPv4PoolError, err:
240
      raise errors.ConfigurationError("Unable to reserve IP: %s", str(err))
241

  
242
    self._config_data.cluster.networks[link]["4"] = network.todict()
243

  
244
  @locking.ssynchronized(_config_lock)
245
  def CommitIp(self, link, address):
246
    """Commit a reserved IP to an IP pool
247

  
248
    This is just a wrapper around _UnlockedCommitIp.
249

  
250
    """
251
    self._UnlockedCommitIp(self, link)
252
    self._WriteConfig()
253

  
254
  def _UnlockedReleaseIp(self, link, address):
255
    """Give a specific IP address back to an IP pool.
256

  
257
    The IP address is returned to the IP pool designated by pool_id and marked
258
    as reserved.
259

  
260
    """
261
    if link is None:
262
      nicparams = self._config_data.cluster.nicparams[constants.VALUE_DEFAULT]
263
      link = nicparams[constants.NIC_LINK]
264

  
265
    if link not in self._config_data.cluster.networks or\
266
      "4" not in self._config_data.cluster.networks[link]:
267
      return
268

  
269
    netdict = self._config_data.cluster.networks[link]["4"]
270
    network = ippool.IPv4Network.fromdict(netdict)
271
    network.release(address)
272
    self._config_data.cluster.networks[link]["4"] = network.todict()
273

  
274
  @locking.ssynchronized(_config_lock)
275
  def ReleaseIp(self, link, address):
276
    """Give a specified IP address back to an IP pool.
277

  
278
    This is just a wrapper around _UnlockedReleaseIp.
279

  
280
    """
281
    self._UnlockedReleaseIp(link, address)
282
    self._WriteConfig()
283

  
284
  @locking.ssynchronized(_config_lock, shared=1)
285
  def GenerateIp(self, link, ec_id):
286
    """Find a free IPv4 address for an instance.
287

  
288
    """
289
    if link is None:
290
      nicparams = self._config_data.cluster.nicparams[constants.VALUE_DEFAULT]
291
      link = nicparams[constants.NIC_LINK]
292

  
293
    if link not in self._config_data.cluster.networks or\
294
      "4" not in self._config_data.cluster.networks[link]:
295
      raise errors.OpPrereqError("No network defined on link %s exists" % link,
296
                                 errors.ECODE_INVAL)
297
    netdict = self._config_data.cluster.networks[link]["4"]
298
    network = ippool.IPv4Network.fromdict(netdict)
299
    return self._temporary_ips.Generate([], network.generate_free(), ec_id)
300

  
301
  @locking.ssynchronized(_config_lock, shared=1)
302
  def ReserveIp(self, link, address, ec_id):
303
    """Reserve a given IPv4 address for use by an instance.
304

  
305
    """
306
    if link is None:
307
      nicparams = self._config_data.cluster.nicparams[constants.VALUE_DEFAULT]
308
      link = nicparams[constants.NIC_LINK]
309

  
310
    if link not in self._config_data.cluster.networks or\
311
      "4" not in self._config_data.cluster.networks[link]:
312
      return
313
    netdict = self._config_data.cluster.networks[link]["4"]
314
    network = ippool.IPv4Network.fromdict(netdict)
315
    network.reserve(address)
316
    return self._temporary_ips.Reserve(address, ec_id)
317

  
217 318
  @locking.ssynchronized(_config_lock, shared=1)
218 319
  def ReserveLV(self, lv_name, ec_id):
219 320
    """Reserve an VG/LV pair for an instance.
......
1087 1188
        raise errors.ConfigurationError("Cannot add instance %s:"
1088 1189
                                        " MAC address '%s' already in use." %
1089 1190
                                        (instance.name, nic.mac))
1191
      # Commit all IP addresses to the respective address pools
1192
      self._UnlockedCommitIp(nic.nicparams.get(constants.NIC_LINK, None),
1193
                             nic.ip)
1090 1194

  
1091 1195
    self._EnsureUUID(instance, ec_id)
1092 1196

  
......
1141 1245
    """
1142 1246
    if instance_name not in self._config_data.instances:
1143 1247
      raise errors.ConfigurationError("Unknown instance '%s'" % instance_name)
1248
    for nic in self._config_data.instances[instance_name].nics:
1249
      # Return all IP addresses to the respective address pools
1250
      self._UnlockedReleaseIp(nic.nicparams.get(constants.NIC_LINK, None),
1251
                              nic.ip)
1144 1252
    del self._config_data.instances[instance_name]
1145 1253
    self._config_data.cluster.serial_no += 1
1146 1254
    self._WriteConfig()
b/lib/objects.py
1087 1087
    "blacklisted_os",
1088 1088
    "primary_ip_family",
1089 1089
    "prealloc_wipe_disks",
1090
    "networks",
1090 1091
    ] + _TIMESTAMPS + _UUID
1091 1092

  
1092 1093
  def UpgradeConfig(self):
......
1173 1174
    if self.shared_file_storage_dir is None:
1174 1175
      self.shared_file_storage_dir = ""
1175 1176

  
1177
    # Network management
1178
    if self.networks is None:
1179
      self.networks = {}
1180

  
1176 1181
  def ToDict(self):
1177 1182
    """Custom function for cluster.
1178 1183

  

Also available in: Unified diff