Revision d1547283 lib/cmdlib.py

b/lib/cmdlib.py
12658 12658
    """
12659 12659
    if op in (constants.DDM_ADD, constants.DDM_MODIFY):
12660 12660
      ip = params.get(constants.INIC_IP, None)
12661
      if ip is None:
12662
        pass
12663
      elif ip.lower() == constants.VALUE_NONE:
12664
        params[constants.INIC_IP] = None
12665
      elif not netutils.IPAddress.IsValid(ip):
12666
        raise errors.OpPrereqError("Invalid IP address '%s'" % ip,
12667
                                   errors.ECODE_INVAL)
12668

  
12669
      bridge = params.get("bridge", None)
12670
      link = params.get(constants.INIC_LINK, None)
12671
      if bridge and link:
12672
        raise errors.OpPrereqError("Cannot pass 'bridge' and 'link'"
12673
                                   " at the same time", errors.ECODE_INVAL)
12674
      elif bridge and bridge.lower() == constants.VALUE_NONE:
12675
        params["bridge"] = None
12676
      elif link and link.lower() == constants.VALUE_NONE:
12677
        params[constants.INIC_LINK] = None
12661
      req_net = params.get(constants.INIC_NETWORK, None)
12662
      link = params.get(constants.NIC_LINK, None)
12663
      mode = params.get(constants.NIC_MODE, None)
12664
      if req_net is not None:
12665
        if req_net.lower() == constants.VALUE_NONE:
12666
          params[constants.INIC_NETWORK] = None
12667
          req_net = None
12668
        elif link is not None or mode is not None:
12669
          raise errors.OpPrereqError("If network is given"
12670
                                     " mode or link should not",
12671
                                     errors.ECODE_INVAL)
12678 12672

  
12679 12673
      if op == constants.DDM_ADD:
12680 12674
        macaddr = params.get(constants.INIC_MAC, None)
12681 12675
        if macaddr is None:
12682 12676
          params[constants.INIC_MAC] = constants.VALUE_AUTO
12683 12677

  
12678
      if ip is not None:
12679
        if ip.lower() == constants.VALUE_NONE:
12680
          params[constants.INIC_IP] = None
12681
        else:
12682
          if ip.lower() == constants.NIC_IP_POOL:
12683
            if op == constants.DDM_ADD and req_net is None:
12684
              raise errors.OpPrereqError("If ip=pool, parameter network"
12685
                                         " cannot be none",
12686
                                         errors.ECODE_INVAL)
12687
          else:
12688
            if not netutils.IPAddress.IsValid(ip):
12689
              raise errors.OpPrereqError("Invalid IP address '%s'" % ip,
12690
                                         errors.ECODE_INVAL)
12691

  
12684 12692
      if constants.INIC_MAC in params:
12685 12693
        macaddr = params[constants.INIC_MAC]
12686 12694
        if macaddr not in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
......
12768 12776
        nicparams = self.cluster.SimpleFillNIC(nic.nicparams)
12769 12777
        mode = nicparams[constants.NIC_MODE]
12770 12778
        link = nicparams[constants.NIC_LINK]
12771
        nics.append((nic.ip, nic.mac, mode, link))
12779
        nics.append((nic.ip, nic.mac, mode, link, nic.network))
12772 12780

  
12773 12781
      args["nics"] = nics
12774 12782

  
......
12787 12795
    nl = [self.cfg.GetMasterNode()] + list(self.instance.all_nodes)
12788 12796
    return (nl, nl)
12789 12797

  
12790
  def _PrepareNicModification(self, params, private, old_ip, old_params,
12791
                              cluster, pnode):
12798
  def _PrepareNicModification(self, params, private, old_ip, old_net,
12799
                              old_params, cluster, pnode):
12800

  
12792 12801
    update_params_dict = dict([(key, params[key])
12793 12802
                               for key in constants.NICS_PARAMETERS
12794 12803
                               if key in params])
12795 12804

  
12796
    if "bridge" in params:
12797
      update_params_dict[constants.NIC_LINK] = params["bridge"]
12805
    req_link = update_params_dict.get(constants.NIC_LINK, None)
12806
    req_mode = update_params_dict.get(constants.NIC_MODE, None)
12807

  
12808
    new_net = params.get(constants.INIC_NETWORK, old_net)
12809
    if new_net is not None:
12810
      netparams = self.cfg.GetGroupNetParams(new_net, pnode)
12811
      if netparams is None:
12812
        raise errors.OpPrereqError("No netparams found for the network"
12813
                                   " %s, propably not connected." % new_net,
12814
                                   errors.ECODE_INVAL)
12815
      new_params = dict(netparams)
12816
    else:
12817
      new_params = _GetUpdatedParams(old_params, update_params_dict)
12798 12818

  
12799
    new_params = _GetUpdatedParams(old_params, update_params_dict)
12800 12819
    utils.ForceDictType(new_params, constants.NICS_PARAMETER_TYPES)
12801 12820

  
12802 12821
    new_filled_params = cluster.SimpleFillNIC(new_params)
......
12836 12855
          raise errors.OpPrereqError("MAC address '%s' already in use"
12837 12856
                                     " in cluster" % mac,
12838 12857
                                     errors.ECODE_NOTUNIQUE)
12858
    elif new_net != old_net:
12859
      def get_net_prefix(net):
12860
        if net:
12861
          uuid = self.cfg.LookupNetwork(net)
12862
          if uuid:
12863
            nobj = self.cfg.GetNetwork(uuid)
12864
            return nobj.mac_prefix
12865
        return None
12866
      new_prefix = get_net_prefix(new_net)
12867
      old_prefix = get_net_prefix(old_net)
12868
      if old_prefix != new_prefix:
12869
        params[constants.INIC_MAC] = \
12870
          self.cfg.GenerateMAC(self.proc.GetECId())
12871

  
12872
    #if there is a change in nic-network configuration
12873
    new_ip = params.get(constants.INIC_IP, old_ip)
12874
    if (new_ip, new_net) != (old_ip, old_net):
12875
      if new_ip:
12876
        if new_net:
12877
          if new_ip.lower() == constants.NIC_IP_POOL:
12878
            try:
12879
              new_ip = self.cfg.GenerateIp(new_net, self.proc.GetECId())
12880
            except errors.ReservationError:
12881
              raise errors.OpPrereqError("Unable to get a free IP"
12882
                                         " from the address pool",
12883
                                         errors.ECODE_STATE)
12884
            self.LogInfo("Chose IP %s from pool %s", new_ip, new_net)
12885
            params[constants.INIC_IP] = new_ip
12886
          elif new_ip != old_ip or new_net != old_net:
12887
            try:
12888
              self.LogInfo("Reserving IP %s in pool %s", new_ip, new_net)
12889
              self.cfg.ReserveIp(new_net, new_ip, self.proc.GetECId())
12890
            except errors.ReservationError:
12891
              raise errors.OpPrereqError("IP %s not available in network %s" %
12892
                                         (new_ip, new_net),
12893
                                         errors.ECODE_NOTUNIQUE)
12894
        elif new_ip.lower() == constants.NIC_IP_POOL:
12895
          raise errors.OpPrereqError("ip=pool, but no network found",
12896
                                     ECODEE_INVAL)
12897
        else:
12898
          # new net is None
12899
          if self.op.conflicts_check:
12900
            _CheckForConflictingIp(self, new_ip, pnode)
12901

  
12902
      if old_ip:
12903
        if old_net:
12904
          try:
12905
            self.cfg.ReleaseIp(old_net, old_ip, self.proc.GetECId())
12906
          except errors.AddressPoolError:
12907
            logging.warning("Release IP %s not contained in network %s",
12908
                            old_ip, old_net)
12909

  
12910
    # there are no changes in (net, ip) tuple
12911
    elif (old_net is not None and
12912
          (req_link is not None or req_mode is not None)):
12913
      raise errors.OpPrereqError("Not allowed to change link or mode of"
12914
                                 " a NIC that is connected to a network.",
12915
                                 errors.ECODE_INVAL)
12839 12916

  
12840 12917
    private.params = new_params
12841 12918
    private.filled = new_filled_params
......
13073 13150
                                 " diskless instances", errors.ECODE_INVAL)
13074 13151

  
13075 13152
    def _PrepareNicCreate(_, params, private):
13076
      self._PrepareNicModification(params, private, None, {}, cluster, pnode)
13153
      self._PrepareNicModification(params, private, None, None,
13154
                                   {}, cluster, pnode)
13077 13155
      return (None, None)
13078 13156

  
13079 13157
    def _PrepareNicMod(_, nic, params, private):
13080
      self._PrepareNicModification(params, private, nic.ip,
13158
      self._PrepareNicModification(params, private, nic.ip, nic.network,
13081 13159
                                   nic.nicparams, cluster, pnode)
13082 13160
      return None
13083 13161

  
13162
    def _PrepareNicRemove(_, params, private):
13163
      ip = params.ip
13164
      net = params.network
13165
      if net is not None and ip is not None:
13166
        self.cfg.ReleaseIp(net, ip, self.proc.GetECId())
13167

  
13084 13168
    # Verify NIC changes (operating on copy)
13085 13169
    nics = instance.nics[:]
13086 13170
    ApplyContainerMods("NIC", nics, None, self.nicmod,
13087
                       _PrepareNicCreate, _PrepareNicMod, None)
13171
                       _PrepareNicCreate, _PrepareNicMod, _PrepareNicRemove)
13088 13172
    if len(nics) > constants.MAX_NICS:
13089 13173
      raise errors.OpPrereqError("Instance has too many network interfaces"
13090 13174
                                 " (%d), cannot add more" % constants.MAX_NICS,
......
13301 13385
    """
13302 13386
    mac = params[constants.INIC_MAC]
13303 13387
    ip = params.get(constants.INIC_IP, None)
13304
    nicparams = private.params
13388
    network = params.get(constants.INIC_NETWORK, None)
13389
    #TODO: not private.filled?? can a nic have no nicparams??
13390
    nicparams = private.filled
13305 13391

  
13306
    return (objects.NIC(mac=mac, ip=ip, nicparams=nicparams), [
13392
    return (objects.NIC(mac=mac, ip=ip, network=network, nicparams=nicparams), [
13307 13393
      ("nic.%d" % idx,
13308
       "add:mac=%s,ip=%s,mode=%s,link=%s" %
13394
       "add:mac=%s,ip=%s,mode=%s,link=%s,network=%s" %
13309 13395
       (mac, ip, private.filled[constants.NIC_MODE],
13310
       private.filled[constants.NIC_LINK])),
13396
       private.filled[constants.NIC_LINK],
13397
       network)),
13311 13398
      ])
13312 13399

  
13313 13400
  @staticmethod
......
13317 13404
    """
13318 13405
    changes = []
13319 13406

  
13320
    for key in [constants.INIC_MAC, constants.INIC_IP]:
13407
    for key in [constants.INIC_MAC, constants.INIC_IP, constants.INIC_NETWORK]:
13321 13408
      if key in params:
13322 13409
        changes.append(("nic.%s/%d" % (key, idx), params[key]))
13323 13410
        setattr(nic, key, params[key])
13324 13411

  
13325
    if private.params:
13326
      nic.nicparams = private.params
13412
    if private.filled:
13413
      nic.nicparams = private.filled
13327 13414

  
13328
      for (key, val) in params.items():
13415
      for (key, val) in nic.nicparams.items():
13329 13416
        changes.append(("nic.%s/%d" % (key, idx), val))
13330 13417

  
13331 13418
    return changes
......
13433 13520
      self.cfg.MarkInstanceDown(instance.name)
13434 13521
      result.append(("admin_state", constants.ADMINST_DOWN))
13435 13522

  
13436
    self.cfg.Update(instance, feedback_fn)
13523
    self.cfg.Update(instance, feedback_fn, self.proc.GetECId())
13437 13524

  
13438 13525
    assert not (self.owned_locks(locking.LEVEL_NODE_RES) or
13439 13526
                self.owned_locks(locking.LEVEL_NODE)), \

Also available in: Unified diff