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