Revision 4b8ec2a1 lib/cmdlib.py

b/lib/cmdlib.py
12579 12579
    """
12580 12580
    if op in (constants.DDM_ADD, constants.DDM_MODIFY):
12581 12581
      ip = params.get(constants.INIC_IP, None)
12582
      if ip is None:
12583
        pass
12584
      elif ip.lower() == constants.VALUE_NONE:
12585
        params[constants.INIC_IP] = None
12586
      elif not netutils.IPAddress.IsValid(ip):
12587
        raise errors.OpPrereqError("Invalid IP address '%s'" % ip,
12588
                                   errors.ECODE_INVAL)
12589

  
12590
      bridge = params.get("bridge", None)
12591
      link = params.get(constants.INIC_LINK, None)
12592
      if bridge and link:
12593
        raise errors.OpPrereqError("Cannot pass 'bridge' and 'link'"
12594
                                   " at the same time", errors.ECODE_INVAL)
12595
      elif bridge and bridge.lower() == constants.VALUE_NONE:
12596
        params["bridge"] = None
12597
      elif link and link.lower() == constants.VALUE_NONE:
12598
        params[constants.INIC_LINK] = None
12582
      req_net = params.get(constants.INIC_NETWORK, None)
12583
      link = params.get(constants.NIC_LINK, None)
12584
      mode = params.get(constants.NIC_MODE, None)
12585
      if req_net is not None:
12586
        if req_net.lower() == constants.VALUE_NONE:
12587
          params[constants.INIC_NETWORK] = None
12588
          req_net = None
12589
        elif link is not None or mode is not None:
12590
          raise errors.OpPrereqError("If network is given"
12591
                                     " mode or link should not",
12592
                                     errors.ECODE_INVAL)
12599 12593

  
12600 12594
      if op == constants.DDM_ADD:
12601 12595
        macaddr = params.get(constants.INIC_MAC, None)
12602 12596
        if macaddr is None:
12603 12597
          params[constants.INIC_MAC] = constants.VALUE_AUTO
12604 12598

  
12599
      if ip is not None:
12600
        if ip.lower() == constants.VALUE_NONE:
12601
          params[constants.INIC_IP] = None
12602
        else:
12603
          if ip.lower() == constants.NIC_IP_POOL:
12604
            if op == constants.DDM_ADD and req_net is None:
12605
              raise errors.OpPrereqError("If ip=pool, parameter network"
12606
                                         " cannot be none",
12607
                                         errors.ECODE_INVAL)
12608
          else:
12609
            if not netutils.IPAddress.IsValid(ip):
12610
              raise errors.OpPrereqError("Invalid IP address '%s'" % ip,
12611
                                         errors.ECODE_INVAL)
12612

  
12605 12613
      if constants.INIC_MAC in params:
12606 12614
        macaddr = params[constants.INIC_MAC]
12607 12615
        if macaddr not in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
......
12689 12697
        nicparams = self.cluster.SimpleFillNIC(nic.nicparams)
12690 12698
        mode = nicparams[constants.NIC_MODE]
12691 12699
        link = nicparams[constants.NIC_LINK]
12692
        nics.append((nic.ip, nic.mac, mode, link))
12700
        nics.append((nic.ip, nic.mac, mode, link, nic.network))
12693 12701

  
12694 12702
      args["nics"] = nics
12695 12703

  
......
12708 12716
    nl = [self.cfg.GetMasterNode()] + list(self.instance.all_nodes)
12709 12717
    return (nl, nl)
12710 12718

  
12711
  def _PrepareNicModification(self, params, private, old_ip, old_params,
12712
                              cluster, pnode):
12719
  def _PrepareNicModification(self, params, private, old_ip, old_net,
12720
                              old_params, cluster, pnode):
12721

  
12713 12722
    update_params_dict = dict([(key, params[key])
12714 12723
                               for key in constants.NICS_PARAMETERS
12715 12724
                               if key in params])
12716 12725

  
12717
    if "bridge" in params:
12718
      update_params_dict[constants.NIC_LINK] = params["bridge"]
12726
    req_link = update_params_dict.get(constants.NIC_LINK, None)
12727
    req_mode = update_params_dict.get(constants.NIC_MODE, None)
12728

  
12729
    new_net = params.get(constants.INIC_NETWORK, old_net)
12730
    if new_net is not None:
12731
      netparams = self.cfg.GetGroupNetParams(new_net, pnode)
12732
      if netparams is None:
12733
        raise errors.OpPrereqError("No netparams found for the network"
12734
                                   " %s, propably not connected." % new_net,
12735
                                   errors.ECODE_INVAL)
12736
      new_params = dict(netparams)
12737
    else:
12738
      new_params = _GetUpdatedParams(old_params, update_params_dict)
12719 12739

  
12720
    new_params = _GetUpdatedParams(old_params, update_params_dict)
12721 12740
    utils.ForceDictType(new_params, constants.NICS_PARAMETER_TYPES)
12722 12741

  
12723 12742
    new_filled_params = cluster.SimpleFillNIC(new_params)
......
12757 12776
          raise errors.OpPrereqError("MAC address '%s' already in use"
12758 12777
                                     " in cluster" % mac,
12759 12778
                                     errors.ECODE_NOTUNIQUE)
12779
    elif new_net != old_net:
12780
      def get_net_prefix(net):
12781
        if net:
12782
          uuid = self.cfg.LookupNetwork(net)
12783
          if uuid:
12784
            nobj = self.cfg.GetNetwork(uuid)
12785
            return nobj.mac_prefix
12786
        return None
12787
      new_prefix = get_net_prefix(new_net)
12788
      old_prefix = get_net_prefix(old_net)
12789
      if old_prefix != new_prefix:
12790
        params[constants.INIC_MAC] = \
12791
          self.cfg.GenerateMAC(self.proc.GetECId())
12792

  
12793
    #if there is a change in nic-network configuration
12794
    new_ip = params.get(constants.INIC_IP, old_ip)
12795
    if (new_ip, new_net) != (old_ip, old_net):
12796
      if new_ip:
12797
        if new_net:
12798
          if new_ip.lower() == constants.NIC_IP_POOL:
12799
            try:
12800
              new_ip = self.cfg.GenerateIp(new_net, self.proc.GetECId())
12801
            except errors.ReservationError:
12802
              raise errors.OpPrereqError("Unable to get a free IP"
12803
                                        " from the address pool",
12804
                                         errors.ECODE_STATE)
12805
            self.LogInfo("Chose IP %s from pool %s", new_ip, new_net)
12806
            params[constants.INIC_IP] = new_ip
12807
          elif new_ip != old_ip or new_net != old_net:
12808
            try:
12809
              self.LogInfo("Reserving IP %s in pool %s", new_ip, new_net)
12810
              self.cfg.ReserveIp(new_net, new_ip, self.proc.GetECId())
12811
            except errors.ReservationError:
12812
              raise errors.OpPrereqError("IP %s not available in network %s" %
12813
                                         (new_ip, new_net),
12814
                                         errors.ECODE_NOTUNIQUE)
12815
        elif new_ip.lower() == constants.NIC_IP_POOL:
12816
          raise errors.OpPrereqError("ip=pool, but no network found",
12817
                                     ECODEE_INVAL)
12818
        else:
12819
          # new net is None
12820
          if self.op.conflicts_check:
12821
            _CheckForConflictingIp(self, new_ip, pnode)
12822

  
12823
      if old_ip:
12824
        if old_net:
12825
          try:
12826
            self.cfg.ReleaseIp(old_net, old_ip, self.proc.GetECId())
12827
          except errors.AddressPoolError:
12828
            logging.warning("Release IP %s not contained in network %s",
12829
                            old_ip, old_net)
12830

  
12831
    # there are no changes in (net, ip) tuple
12832
    elif (old_net is not None and
12833
          (req_link is not None or req_mode is not None)):
12834
      raise errors.OpPrereqError("Not allowed to change link or mode of"
12835
                                 " a NIC that is connected to a network.",
12836
                                 errors.ECODE_INVAL)
12760 12837

  
12761 12838
    private.params = new_params
12762 12839
    private.filled = new_filled_params
......
12995 13072
                                 " diskless instances", errors.ECODE_INVAL)
12996 13073

  
12997 13074
    def _PrepareNicCreate(_, params, private):
12998
      self._PrepareNicModification(params, private, None, {}, cluster, pnode)
13075
      self._PrepareNicModification(params, private, None, None,
13076
                                   {}, cluster, pnode)
12999 13077
      return (None, None)
13000 13078

  
13001 13079
    def _PrepareNicMod(_, nic, params, private):
13002
      self._PrepareNicModification(params, private, nic.ip,
13080
      self._PrepareNicModification(params, private, nic.ip, nic.network,
13003 13081
                                   nic.nicparams, cluster, pnode)
13004 13082
      return None
13005 13083

  
13084
    def _PrepareNicRemove(_, params, private):
13085
      ip = params.ip
13086
      net = params.network
13087
      if net is not None and ip is not None:
13088
        self.cfg.ReleaseIp(net, ip, self.proc.GetECId())
13089

  
13006 13090
    # Verify NIC changes (operating on copy)
13007 13091
    nics = instance.nics[:]
13008 13092
    ApplyContainerMods("NIC", nics, None, self.nicmod,
13009
                       _PrepareNicCreate, _PrepareNicMod, None)
13093
                       _PrepareNicCreate, _PrepareNicMod, _PrepareNicRemove)
13010 13094
    if len(nics) > constants.MAX_NICS:
13011 13095
      raise errors.OpPrereqError("Instance has too many network interfaces"
13012 13096
                                 " (%d), cannot add more" % constants.MAX_NICS,
......
13223 13307
    """
13224 13308
    mac = params[constants.INIC_MAC]
13225 13309
    ip = params.get(constants.INIC_IP, None)
13226
    nicparams = private.params
13310
    network = params.get(constants.INIC_NETWORK, None)
13311
    #TODO: not private.filled?? can a nic have no nicparams??
13312
    nicparams = private.filled
13227 13313

  
13228
    return (objects.NIC(mac=mac, ip=ip, nicparams=nicparams), [
13314
    return (objects.NIC(mac=mac, ip=ip, network=network, nicparams=nicparams), [
13229 13315
      ("nic.%d" % idx,
13230
       "add:mac=%s,ip=%s,mode=%s,link=%s" %
13316
       "add:mac=%s,ip=%s,mode=%s,link=%s,network=%s" %
13231 13317
       (mac, ip, private.filled[constants.NIC_MODE],
13232
       private.filled[constants.NIC_LINK])),
13318
       private.filled[constants.NIC_LINK],
13319
       network)),
13233 13320
      ])
13234 13321

  
13235 13322
  @staticmethod
......
13239 13326
    """
13240 13327
    changes = []
13241 13328

  
13242
    for key in [constants.INIC_MAC, constants.INIC_IP]:
13329
    for key in [constants.INIC_MAC, constants.INIC_IP, constants.INIC_NETWORK]:
13243 13330
      if key in params:
13244 13331
        changes.append(("nic.%s/%d" % (key, idx), params[key]))
13245 13332
        setattr(nic, key, params[key])
13246 13333

  
13247
    if private.params:
13248
      nic.nicparams = private.params
13334
    if private.filled:
13335
      nic.nicparams = private.filled
13249 13336

  
13250
      for (key, val) in params.items():
13337
      for (key, val) in nic.nicparams.items():
13251 13338
        changes.append(("nic.%s/%d" % (key, idx), val))
13252 13339

  
13253 13340
    return changes
......
13355 13442
      self.cfg.MarkInstanceDown(instance.name)
13356 13443
      result.append(("admin_state", constants.ADMINST_DOWN))
13357 13444

  
13358
    self.cfg.Update(instance, feedback_fn)
13445
    self.cfg.Update(instance, feedback_fn, self.proc.GetECId())
13359 13446

  
13360 13447
    assert not (self.owned_locks(locking.LEVEL_NODE_RES) or
13361 13448
                self.owned_locks(locking.LEVEL_NODE)), \

Also available in: Unified diff