diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 34f012f669178efa05b30df1d44f218683fec12c..22879aec76a733ae12eda340ec3d08526f411509 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -7720,6 +7720,24 @@ class LUInstanceCreate(LogicalUnit): if nic_mode is None: nic_mode = cluster.nicparams[constants.PP_DEFAULT][constants.NIC_MODE] + # bridge verification + bridge = nic.get("bridge", None) + link = nic.get("link", None) + if bridge and link: + raise errors.OpPrereqError("Cannot pass 'bridge' and 'link'" + " at the same time", errors.ECODE_INVAL) + elif bridge and nic_mode == constants.NIC_MODE_ROUTED: + raise errors.OpPrereqError("Cannot pass 'bridge' on a routed nic", + errors.ECODE_INVAL) + elif bridge: + link = bridge + + nicparams = {} + if nic_mode_req: + nicparams[constants.NIC_MODE] = nic_mode_req + if link: + nicparams[constants.NIC_LINK] = link + # in routed mode, for the first nic, the default ip is 'auto' if nic_mode == constants.NIC_MODE_ROUTED and idx == 0: default_ip_mode = constants.VALUE_AUTO @@ -7736,11 +7754,26 @@ class LUInstanceCreate(LogicalUnit): " have been skipped", errors.ECODE_INVAL) nic_ip = self.hostname1.ip + try: + self.cfg.ReserveIp(link, nic_ip, self.proc.GetECId()) + except errors.ReservationError: + raise errors.OpPrereqError("IP address %s already in use" + " in cluster" % nic_ip, + errors.ECODE_NOTUNIQUE) + elif ip.lower() == constants.NIC_IP_POOL: + nic_ip = self.cfg.GenerateIp(link, self.proc.GetECId()) + logging.info("Chose ip %s from pool %s" % (nic_ip, link)) else: if not netutils.IPAddress.IsValid(ip): raise errors.OpPrereqError("Invalid IP address '%s'" % ip, errors.ECODE_INVAL) nic_ip = ip + try: + self.cfg.ReserveIp(link, nic_ip, self.proc.GetECId()) + except errors.ReservationError: + raise errors.OpPrereqError("IP address %s already in use" + " in cluster" % nic_ip, + errors.ECODE_NOTUNIQUE) # TODO: check the ip address for uniqueness if nic_mode == constants.NIC_MODE_ROUTED and not nic_ip: @@ -7759,24 +7792,6 @@ class LUInstanceCreate(LogicalUnit): " in cluster" % mac, errors.ECODE_NOTUNIQUE) - # bridge verification - bridge = nic.get("bridge", None) - link = nic.get("link", None) - if bridge and link: - raise errors.OpPrereqError("Cannot pass 'bridge' and 'link'" - " at the same time", errors.ECODE_INVAL) - elif bridge and nic_mode == constants.NIC_MODE_ROUTED: - raise errors.OpPrereqError("Cannot pass 'bridge' on a routed nic", - errors.ECODE_INVAL) - elif bridge: - link = bridge - - nicparams = {} - if nic_mode_req: - nicparams[constants.NIC_MODE] = nic_mode_req - if link: - nicparams[constants.NIC_LINK] = link - check_params = cluster.SimpleFillNIC(nicparams) objects.NIC.CheckParameterSyntax(check_params) self.nics.append(objects.NIC(mac=mac, ip=nic_ip, nicparams=nicparams)) diff --git a/lib/constants.py b/lib/constants.py index 2c1d91c1b37b23ac4852f0047aadd297bc61c2ae..85e6dcd2379a30e9962f6f46b2ee8b1f1bd0714d 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -738,6 +738,8 @@ NIC_LINK = "link" NIC_MODE_BRIDGED = "bridged" NIC_MODE_ROUTED = "routed" +NIC_IP_POOL = "pool" + NIC_VALID_MODES = frozenset([NIC_MODE_BRIDGED, NIC_MODE_ROUTED]) NICS_PARAMETER_TYPES = {