Sorry, I forgot the list on my comments.
The only problem I had with the patch is that it adds locking "at the
same time" as doing the other changes, which makes it quite big and
confusing. I believe locking should be added separately.

Thanks,

Guido

On Fri, Feb 15, 2013 at 1:52 PM, Helga Velroyen <[email protected]> wrote:
> Hi!
>
> LGTM. This will cause some changes in the Haskell code base. I will push
> this (if noone objects) and send the Haskell patches myself, since I am
> working on related stuff anyway.
>
> Cheers,
> Helga
>
>
> On Thu, Feb 14, 2013 at 3:06 PM, Dimitris Aragiorgis <[email protected]>
> wrote:
>>
>> Network name and other info is filled temporarily in netinfo slot.
>>
>> Export network name during instance queries.
>>
>> To do so, all the info for the instance's networks must be stored in
>> InstanceQueryData context. Introduce new cfg method GetInstanceNetworks()
>> that returns all networks (uuids) of the instance's nics.
>>
>> LUInstanceQueryData fills NIC data just like as hooks do so we have
>> all the necessary info in netinfo slot.
>>
>> Locking is implemented in DeclareLocks easily because networks are locked
>> at the time when locks for wanted instances have been aquired.
>>
>> Signed-off-by: Dimitris Aragiorgis <[email protected]>
>> ---
>>  lib/backend.py             |    5 --
>>  lib/client/gnt_instance.py |    4 +-
>>  lib/cmdlib.py              |  166
>> ++++++++++++++++++++++++++------------------
>>  lib/config.py              |   51 +++++++++-----
>>  lib/query.py               |   49 ++++++++++++-
>>  5 files changed, 179 insertions(+), 96 deletions(-)
>>
>> diff --git a/lib/backend.py b/lib/backend.py
>> index cf28d4f..569a616 100644
>> --- a/lib/backend.py
>> +++ b/lib/backend.py
>> @@ -2501,11 +2501,6 @@ def OSEnvironment(instance, inst_os, debug=0):
>>      if nic.netinfo:
>>        nobj = objects.Network.FromDict(nic.netinfo)
>>        result.update(nobj.HooksDict("NIC_%d_" % idx))
>> -    elif nic.network:
>> -      # FIXME: broken network reference: the instance NIC specifies a
>> network,
>> -      # but the relevant network entry was not in the config. This should
>> be
>> -      # made impossible.
>> -      result["INSTANCE_NIC%d_NETWORK" % idx] = nic.network
>>      if constants.HV_NIC_TYPE in instance.hvparams:
>>        result["NIC_%d_FRONTEND_TYPE" % idx] = \
>>          instance.hvparams[constants.HV_NIC_TYPE]
>> diff --git a/lib/client/gnt_instance.py b/lib/client/gnt_instance.py
>> index ee9bf44..f223566 100644
>> --- a/lib/client/gnt_instance.py
>> +++ b/lib/client/gnt_instance.py
>> @@ -1177,10 +1177,10 @@ def ShowInstanceConfig(opts, args):
>>      FormatParameterDict(buf, instance["be_instance"], be_actual, level=2)
>>      # TODO(ganeti 2.7) rework the NICs as well
>>      buf.write("    - NICs:\n")
>> -    for idx, (ip, mac, mode, link, network, _) in
>> enumerate(instance["nics"]):
>> +    for idx, (ip, mac, mode, link, _, netinfo) in
>> enumerate(instance["nics"]):
>>        buf.write("      - nic/%d: MAC: %s, IP: %s,"
>>                  " mode: %s, link: %s, network: %s\n" %
>> -                (idx, mac, ip, mode, link, network))
>> +                (idx, mac, ip, mode, link, netinfo["name"]))
>>      buf.write("  Disk template: %s\n" % instance["disk_template"])
>>      buf.write("  Disks:\n")
>>
>> diff --git a/lib/cmdlib.py b/lib/cmdlib.py
>> index 3637644..8ec5946 100644
>> --- a/lib/cmdlib.py
>> +++ b/lib/cmdlib.py
>> @@ -1557,9 +1557,8 @@ def _NICToTuple(lu, nic):
>>    link = filled_params[constants.NIC_LINK]
>>    netinfo = None
>>    if nic.network:
>> -    net_uuid = lu.cfg.LookupNetwork(nic.network)
>> -    netinfo = objects.Network.ToDict(lu.cfg.GetNetwork(net_uuid))
>> -
>> +    nobj = lu.cfg.GetNetwork(nic.network)
>> +    netinfo = objects.Network.ToDict(nobj)
>>    return (nic.ip, nic.mac, mode, link, nic.network, netinfo)
>>
>>
>> @@ -5752,6 +5751,7 @@ class _InstanceQuery(_QueryBase):
>>        lu.needed_locks[locking.LEVEL_INSTANCE] = self.wanted
>>        lu.needed_locks[locking.LEVEL_NODEGROUP] = []
>>        lu.needed_locks[locking.LEVEL_NODE] = []
>> +      lu.needed_locks[locking.LEVEL_NETWORK] = []
>>        lu.recalculate_locks[locking.LEVEL_NODE] = constants.LOCKS_REPLACE
>>
>>      self.do_grouplocks = (self.do_locking and
>> @@ -5771,6 +5771,12 @@ class _InstanceQuery(_QueryBase):
>>        elif level == locking.LEVEL_NODE:
>>          lu._LockInstancesNodes() # pylint: disable=W0212
>>
>> +      elif level == locking.LEVEL_NETWORK:
>> +        lu.needed_locks[locking.LEVEL_NETWORK] = \
>> +          frozenset(net_uuid
>> +                    for instance_name in
>> lu.owned_locks(locking.LEVEL_INSTANCE)
>> +                    for net_uuid in
>> lu.cfg.GetInstanceNetworks(instance_name))
>> +
>>    @staticmethod
>>    def _CheckGroupLocks(lu):
>>      owned_instances = frozenset(lu.owned_locks(locking.LEVEL_INSTANCE))
>> @@ -5861,10 +5867,17 @@ class _InstanceQuery(_QueryBase):
>>        nodes = None
>>        groups = None
>>
>> +    if query.IQ_NETWORKS in self.requested_data:
>> +      net_uuids = itertools.chain(*(lu.cfg.GetInstanceNetworks(i.name)
>> +                                    for i in instance_list))
>> +      networks = dict((uuid, lu.cfg.GetNetwork(uuid)) for uuid in
>> net_uuids)
>> +    else:
>> +      networks = None
>> +
>>      return query.InstanceQueryData(instance_list,
>> lu.cfg.GetClusterInfo(),
>>                                     disk_usage, offline_nodes, bad_nodes,
>>                                     live_data, wrongnode_inst, consinfo,
>> -                                   nodes, groups)
>> +                                   nodes, groups, networks)
>>
>>
>>  class LUQuery(NoHooksLU):
>> @@ -9950,8 +9963,9 @@ def _ComputeNics(op, cluster, default_ip, cfg,
>> ec_id):
>>
>>      check_params = cluster.SimpleFillNIC(nicparams)
>>      objects.NIC.CheckParameterSyntax(check_params)
>> +    net_uuid = cfg.LookupNetwork(net)
>>      nics.append(objects.NIC(mac=mac, ip=nic_ip,
>> -                            network=net, nicparams=nicparams))
>> +                            network=net_uuid, nicparams=nicparams))
>>
>>    return nics
>>
>> @@ -10687,14 +10701,15 @@ class LUInstanceCreate(LogicalUnit):
>>      # Fill in any IPs from IP pools. This must happen here, because we
>> need to
>>      # know the nic's primary node, as specified by the iallocator
>>      for idx, nic in enumerate(self.nics):
>> -      net = nic.network
>> -      if net is not None:
>> -        netparams = self.cfg.GetGroupNetParams(net, self.pnode.name)
>> +      net_uuid = nic.network
>> +      if net_uuid is not None:
>> +        nobj = self.cfg.GetNetwork(net_uuid)
>> +        netparams = self.cfg.GetGroupNetParams(net_uuid, self.pnode.name)
>>          if netparams is None:
>>            raise errors.OpPrereqError("No netparams found for network"
>>                                       " %s. Propably not connected to"
>>                                       " node's %s nodegroup" %
>> -                                     (net, self.pnode.name),
>> +                                     (nobj.name, self.pnode.name),
>>                                       errors.ECODE_INVAL)
>>          self.LogInfo("NIC/%d inherits netparams %s" %
>>                       (idx, netparams.values()))
>> @@ -10702,19 +10717,19 @@ class LUInstanceCreate(LogicalUnit):
>>          if nic.ip is not None:
>>            if nic.ip.lower() == constants.NIC_IP_POOL:
>>              try:
>> -              nic.ip = self.cfg.GenerateIp(net, self.proc.GetECId())
>> +              nic.ip = self.cfg.GenerateIp(net_uuid, self.proc.GetECId())
>>              except errors.ReservationError:
>>                raise errors.OpPrereqError("Unable to get a free IP for NIC
>> %d"
>>                                           " from the address pool" % idx,
>>                                           errors.ECODE_STATE)
>> -            self.LogInfo("Chose IP %s from network %s", nic.ip, net)
>> +            self.LogInfo("Chose IP %s from network %s", nic.ip,
>> nobj.name)
>>            else:
>>              try:
>> -              self.cfg.ReserveIp(net, nic.ip, self.proc.GetECId())
>> +              self.cfg.ReserveIp(net_uuid, nic.ip, self.proc.GetECId())
>>              except errors.ReservationError:
>>                raise errors.OpPrereqError("IP address %s already in use"
>>                                           " or does not belong to network
>> %s" %
>> -                                         (nic.ip, net),
>> +                                         (nic.ip, nobj.name),
>>                                           errors.ECODE_NOTUNIQUE)
>>
>>        # net is None, ip None or given
>> @@ -12815,12 +12830,13 @@ class LUInstanceQueryData(NoHooksLU):
>>
>>        self.needed_locks[locking.LEVEL_NODEGROUP] = []
>>        self.needed_locks[locking.LEVEL_NODE] = []
>> +      self.needed_locks[locking.LEVEL_NETWORK] = []
>>        self.recalculate_locks[locking.LEVEL_NODE] =
>> constants.LOCKS_REPLACE
>>
>>    def DeclareLocks(self, level):
>>      if self.op.use_locking:
>> +      owned_instances = self.owned_locks(locking.LEVEL_INSTANCE)
>>        if level == locking.LEVEL_NODEGROUP:
>> -        owned_instances = self.owned_locks(locking.LEVEL_INSTANCE)
>>
>>          # Lock all groups used by instances optimistically; this requires
>> going
>>          # via the node before it's locked, requiring verification later
>> on
>> @@ -12833,6 +12849,13 @@ class LUInstanceQueryData(NoHooksLU):
>>        elif level == locking.LEVEL_NODE:
>>          self._LockInstancesNodes()
>>
>> +      elif level == locking.LEVEL_NETWORK:
>> +        self.needed_locks[locking.LEVEL_NETWORK] = \
>> +          frozenset(net_uuid
>> +                    for instance_name in owned_instances
>> +                    for net_uuid in
>> +                       self.cfg.GetInstanceNetworks(instance_name))
>> +
>>    def CheckPrereq(self):
>>      """Check prerequisites.
>>
>> @@ -12842,6 +12865,7 @@ class LUInstanceQueryData(NoHooksLU):
>>      owned_instances = frozenset(self.owned_locks(locking.LEVEL_INSTANCE))
>>      owned_groups = frozenset(self.owned_locks(locking.LEVEL_NODEGROUP))
>>      owned_nodes = frozenset(self.owned_locks(locking.LEVEL_NODE))
>> +    owned_networks = frozenset(self.owned_locks(locking.LEVEL_NETWORK))
>>
>>      if self.wanted_names is None:
>>        assert self.op.use_locking, "Locking was not used"
>> @@ -12853,7 +12877,8 @@ class LUInstanceQueryData(NoHooksLU):
>>        _CheckInstancesNodeGroups(self.cfg, instances, owned_groups,
>> owned_nodes,
>>                                  None)
>>      else:
>> -      assert not (owned_instances or owned_groups or owned_nodes)
>> +      assert not (owned_instances or owned_groups or
>> +                  owned_nodes or owned_networks)
>>
>>      self.wanted_instances = instances.values()
>>
>> @@ -12937,7 +12962,6 @@ class LUInstanceQueryData(NoHooksLU):
>>                                                   for node in
>> nodes.values()))
>>
>>      group2name_fn = lambda uuid: groups[uuid].name
>> -
>>      for instance in self.wanted_instances:
>>        pnode = nodes[instance.primary_node]
>>
>> @@ -13381,7 +13405,7 @@ class LUInstanceSetParams(LogicalUnit):
>>      nl = [self.cfg.GetMasterNode()] + list(self.instance.all_nodes)
>>      return (nl, nl)
>>
>> -  def _PrepareNicModification(self, params, private, old_ip, old_net,
>> +  def _PrepareNicModification(self, params, private, old_ip,
>> old_net_uuid,
>>                                old_params, cluster, pnode):
>>
>>      update_params_dict = dict([(key, params[key])
>> @@ -13391,13 +13415,21 @@ class LUInstanceSetParams(LogicalUnit):
>>      req_link = update_params_dict.get(constants.NIC_LINK, None)
>>      req_mode = update_params_dict.get(constants.NIC_MODE, None)
>>
>> -    new_net = params.get(constants.INIC_NETWORK, old_net)
>> -    if new_net is not None:
>> -      netparams = self.cfg.GetGroupNetParams(new_net, pnode)
>> -      if netparams is None:
>> +    new_net_uuid = None
>> +    new_net_uuid_or_name = params.get(constants.INIC_NETWORK,
>> old_net_uuid)
>> +    if new_net_uuid_or_name:
>> +      new_net_uuid = self.cfg.LookupNetwork(new_net_uuid_or_name)
>> +      new_net_obj = self.cfg.GetNetwork(new_net_uuid)
>> +
>> +    if old_net_uuid:
>> +      old_net_obj = self.cfg.GetNetwork(old_net_uuid)
>> +
>> +    if new_net_uuid:
>> +      netparams = self.cfg.GetGroupNetParams(new_net_uuid, pnode)
>> +      if not netparams:
>>          raise errors.OpPrereqError("No netparams found for the network"
>> -                                   " %s, probably not connected" %
>> new_net,
>> -                                   errors.ECODE_INVAL)
>> +                                   " %s, probably not connected" %
>> +                                   new_net_obj.name, errors.ECODE_INVAL)
>>        new_params = dict(netparams)
>>      else:
>>        new_params = _GetUpdatedParams(old_params, update_params_dict)
>> @@ -13436,7 +13468,7 @@ class LUInstanceSetParams(LogicalUnit):
>>        elif mac in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
>>          # otherwise generate the MAC address
>>          params[constants.INIC_MAC] = \
>> -          self.cfg.GenerateMAC(new_net, self.proc.GetECId())
>> +          self.cfg.GenerateMAC(new_net_uuid, self.proc.GetECId())
>>        else:
>>          # or validate/reserve the current one
>>          try:
>> @@ -13445,61 +13477,61 @@ class LUInstanceSetParams(LogicalUnit):
>>            raise errors.OpPrereqError("MAC address '%s' already in use"
>>                                       " in cluster" % mac,
>>                                       errors.ECODE_NOTUNIQUE)
>> -    elif new_net != old_net:
>> +    elif new_net_uuid != old_net_uuid:
>>
>> -      def get_net_prefix(net):
>> +      def get_net_prefix(net_uuid):
>>          mac_prefix = None
>> -        if net:
>> -          uuid = self.cfg.LookupNetwork(net)
>> -          mac_prefix = self.cfg.GetNetwork(uuid).mac_prefix
>> +        if net_uuid:
>> +          nobj = self.cfg.GetNetwork(net_uuid)
>> +          mac_prefix = nobj.mac_prefix
>>
>>          return mac_prefix
>>
>> -      new_prefix = get_net_prefix(new_net)
>> -      old_prefix = get_net_prefix(old_net)
>> +      new_prefix = get_net_prefix(new_net_uuid)
>> +      old_prefix = get_net_prefix(old_net_uuid)
>>        if old_prefix != new_prefix:
>>          params[constants.INIC_MAC] = \
>> -          self.cfg.GenerateMAC(new_net, self.proc.GetECId())
>> +          self.cfg.GenerateMAC(new_net_uuid, self.proc.GetECId())
>>
>> -    #if there is a change in nic-network configuration
>> +    #if there is a change in nic's ip/network configuration
>>      new_ip = params.get(constants.INIC_IP, old_ip)
>> -    if (new_ip, new_net) != (old_ip, old_net):
>> +    if (new_ip, new_net_uuid) != (old_ip, old_net_uuid):
>>        if new_ip:
>> -        if new_net:
>> -          if new_ip.lower() == constants.NIC_IP_POOL:
>> -            try:
>> -              new_ip = self.cfg.GenerateIp(new_net, self.proc.GetECId())
>> -            except errors.ReservationError:
>> -              raise errors.OpPrereqError("Unable to get a free IP"
>> -                                         " from the address pool",
>> -                                         errors.ECODE_STATE)
>> -            self.LogInfo("Chose IP %s from pool %s", new_ip, new_net)
>> -            params[constants.INIC_IP] = new_ip
>> -          elif new_ip != old_ip or new_net != old_net:
>> -            try:
>> -              self.LogInfo("Reserving IP %s in pool %s", new_ip, new_net)
>> -              self.cfg.ReserveIp(new_net, new_ip, self.proc.GetECId())
>> -            except errors.ReservationError:
>> -              raise errors.OpPrereqError("IP %s not available in network
>> %s" %
>> -                                         (new_ip, new_net),
>> -                                         errors.ECODE_NOTUNIQUE)
>> -        elif new_ip.lower() == constants.NIC_IP_POOL:
>> -          raise errors.OpPrereqError("ip=pool, but no network found",
>> -                                     errors.ECODE_INVAL)
>> +        if new_ip.lower() == constants.NIC_IP_POOL:
>> +          if not new_net_uuid:
>> +            raise errors.OpPrereqError("ip=pool, but no network found",
>> +                                       errors.ECODE_INVAL)
>> +          try:
>> +            new_ip = self.cfg.GenerateIp(new_net_uuid,
>> self.proc.GetECId())
>> +          except errors.ReservationError:
>> +            raise errors.OpPrereqError("Unable to get a free IP"
>> +                                       " from the address pool",
>> +                                       errors.ECODE_STATE)
>> +          self.LogInfo("Chose IP %s from network %s", new_ip,
>> new_net_obj.name)
>> +          params[constants.INIC_IP] = new_ip
>> +        elif new_ip != old_ip or new_net_uuid != old_net_uuid:
>> +          try:
>> +            self.cfg.ReserveIp(new_net_uuid, new_ip, self.proc.GetECId())
>> +            self.LogInfo("Reserving IP %s in network %s",
>> +                         new_ip, new_net_obj.name)
>> +          except errors.ReservationError:
>> +            raise errors.OpPrereqError("IP %s not available in network
>> %s" %
>> +                                       (new_ip, new_net_obj.name),
>> +                                       errors.ECODE_NOTUNIQUE)
>>
>>          # new net is None
>> -        elif self.op.conflicts_check:
>> +        elif not new_net_uuid and self.op.conflicts_check:
>>            _CheckForConflictingIp(self, new_ip, pnode)
>>
>> -      if old_ip and old_net:
>> +      if old_ip:
>>          try:
>> -          self.cfg.ReleaseIp(old_net, old_ip, self.proc.GetECId())
>> -        except errors.AddressPoolError, err:
>> -          logging.warning("Releasing IP address '%s' from network '%s'"
>> -                          " failed: %s", old_ip, old_net, err)
>> +          self.cfg.ReleaseIp(old_net_uuid, old_ip, self.proc.GetECId())
>> +        except errors.AddressPoolError:
>> +          logging.warning("Release IP %s not contained in network %s",
>> +                          old_ip, old_net_obj.name)
>>
>>      # there are no changes in (net, ip) tuple
>> -    elif (old_net is not None and
>> +    elif (old_net_uuid is not None and
>>            (req_link is not None or req_mode is not None)):
>>        raise errors.OpPrereqError("Not allowed to change link or mode of"
>>                                   " a NIC that is connected to a network",
>> @@ -16534,8 +16566,6 @@ class _NetworkQuery(_QueryBase):
>>      network_uuids = self._GetNames(lu, all_networks.keys(),
>>                                     locking.LEVEL_NETWORK)
>>
>> -    name_to_uuid = dict((n.name, n.uuid) for n in all_networks.values())
>> -
>>      do_instances = query.NETQ_INST in self.requested_data
>>      do_groups = query.NETQ_GROUP in self.requested_data
>>
>> @@ -16560,10 +16590,8 @@ class _NetworkQuery(_QueryBase):
>>        network_to_instances = dict((uuid, []) for uuid in network_uuids)
>>        for instance in all_instances.values():
>>          for nic in instance.nics:
>> -          if nic.network:
>> -            net_uuid = name_to_uuid[nic.network]
>> -            if net_uuid in network_uuids:
>> -              network_to_instances[net_uuid].append(instance.name)
>> +          if nic.network in network_uuids:
>> +            network_to_instances[nic.network].append(instance.name)
>>              break
>>
>>      if query.NETQ_STATS in self.requested_data:
>> @@ -16795,7 +16823,7 @@ class LUNetworkDisconnect(LogicalUnit):
>>        self.connected = False
>>        return
>>
>> -    _NetworkConflictCheck(self, lambda nic: nic.network ==
>> self.network_name,
>> +    _NetworkConflictCheck(self, lambda nic: nic.network ==
>> self.network_uuid,
>>                            "disconnect from")
>>
>>    def Exec(self, feedback_fn):
>> diff --git a/lib/config.py b/lib/config.py
>> index 4f8c36d..3b20177 100644
>> --- a/lib/config.py
>> +++ b/lib/config.py
>> @@ -270,13 +270,12 @@ class ConfigWriter:
>>      """
>>      return self._config_data.cluster.SimpleFillDP(group.diskparams)
>>
>> -  def _UnlockedGetNetworkMACPrefix(self, net):
>> +  def _UnlockedGetNetworkMACPrefix(self, net_uuid):
>>      """Return the network mac prefix if it exists or the cluster level
>> default.
>>
>>      """
>>      prefix = None
>> -    if net:
>> -      net_uuid = self._UnlockedLookupNetwork(net)
>> +    if net_uuid:
>>        nobj = self._UnlockedGetNetwork(net_uuid)
>>        if nobj.mac_prefix:
>>          prefix = nobj.mac_prefix
>> @@ -302,14 +301,14 @@ class ConfigWriter:
>>      return GenMac
>>
>>    @locking.ssynchronized(_config_lock, shared=1)
>> -  def GenerateMAC(self, net, ec_id):
>> +  def GenerateMAC(self, net_uuid, ec_id):
>>      """Generate a MAC for an instance.
>>
>>      This should check the current instances for duplicates.
>>
>>      """
>>      existing = self._AllMACs()
>> -    prefix = self._UnlockedGetNetworkMACPrefix(net)
>> +    prefix = self._UnlockedGetNetworkMACPrefix(net_uuid)
>>      gen_mac = self._GenerateOneMAC(prefix)
>>      return self._temporary_ids.Generate(existing, gen_mac, ec_id)
>>
>> @@ -358,21 +357,20 @@ class ConfigWriter:
>>                                  (constants.RELEASE_ACTION, address,
>> net_uuid))
>>
>>    @locking.ssynchronized(_config_lock, shared=1)
>> -  def ReleaseIp(self, net, address, ec_id):
>> +  def ReleaseIp(self, net_uuid, address, ec_id):
>>      """Give a specified IP address back to an IP pool.
>>
>>      This is just a wrapper around _UnlockedReleaseIp.
>>
>>      """
>> -    net_uuid = self._UnlockedLookupNetwork(net)
>> -    self._UnlockedReleaseIp(net_uuid, address, ec_id)
>> +    if net_uuid:
>> +      self._UnlockedReleaseIp(net_uuid, address, ec_id)
>>
>>    @locking.ssynchronized(_config_lock, shared=1)
>> -  def GenerateIp(self, net, ec_id):
>> +  def GenerateIp(self, net_uuid, ec_id):
>>      """Find a free IPv4 address for an instance.
>>
>>      """
>> -    net_uuid = self._UnlockedLookupNetwork(net)
>>      nobj = self._UnlockedGetNetwork(net_uuid)
>>      pool = network.AddressPool(nobj)
>>
>> @@ -404,12 +402,12 @@ class ConfigWriter:
>>                                          address, net_uuid))
>>
>>    @locking.ssynchronized(_config_lock, shared=1)
>> -  def ReserveIp(self, net, address, ec_id):
>> +  def ReserveIp(self, net_uuid, address, ec_id):
>>      """Reserve a given IPv4 address for use by an instance.
>>
>>      """
>> -    net_uuid = self._UnlockedLookupNetwork(net)
>> -    return self._UnlockedReserveIp(net_uuid, address, ec_id)
>> +    if net_uuid:
>> +      return self._UnlockedReserveIp(net_uuid, address, ec_id)
>>
>>    @locking.ssynchronized(_config_lock, shared=1)
>>    def ReserveLV(self, lv_name, ec_id):
>> @@ -1574,6 +1572,24 @@ class ConfigWriter:
>>                       for node_name in nodes)
>>
>>    @locking.ssynchronized(_config_lock, shared=1)
>> +  def GetInstanceNetworks(self, instance_name):
>> +    """Returns set of network UUIDs for instance's nics.
>> +
>> +    @rtype: frozenset
>> +
>> +    """
>> +    instance = self._UnlockedGetInstanceInfo(instance_name)
>> +    if not instance:
>> +      raise errors.ConfigurationError("Unknown instance '%s'" %
>> instance_name)
>> +
>> +    networks = set()
>> +    for nic in instance.nics:
>> +      if nic.network:
>> +        networks.add(nic.network)
>> +
>> +    return frozenset(networks)
>> +
>> +  @locking.ssynchronized(_config_lock, shared=1)
>>    def GetMultiInstanceInfo(self, instances):
>>      """Get the configuration of multiple instances.
>>
>> @@ -2526,20 +2542,19 @@ class ConfigWriter:
>>      self._config_data.cluster.serial_no += 1
>>      self._WriteConfig()
>>
>> -  def _UnlockedGetGroupNetParams(self, net, node):
>> +  def _UnlockedGetGroupNetParams(self, net_uuid, node):
>>      """Get the netparams (mode, link) of a network.
>>
>>      Get a network's netparams for a given node.
>>
>>      @type net: string
>> -    @param net: network name
>> +    @param net: network uuid
>>      @type node: string
>>      @param node: node name
>>      @rtype: dict or None
>>      @return: netparams
>>
>>      """
>> -    net_uuid = self._UnlockedLookupNetwork(net)
>>      node_info = self._UnlockedGetNodeInfo(node)
>>      nodegroup_info = self._UnlockedGetNodeGroup(node_info.group)
>>      netparams = nodegroup_info.networks.get(net_uuid, None)
>> @@ -2547,11 +2562,11 @@ class ConfigWriter:
>>      return netparams
>>
>>    @locking.ssynchronized(_config_lock, shared=1)
>> -  def GetGroupNetParams(self, net, node):
>> +  def GetGroupNetParams(self, net_uuid, node):
>>      """Locking wrapper of _UnlockedGetGroupNetParams()
>>
>>      """
>> -    return self._UnlockedGetGroupNetParams(net, node)
>> +    return self._UnlockedGetGroupNetParams(net_uuid, node)
>>
>>    @locking.ssynchronized(_config_lock, shared=1)
>>    def CheckIPInNodeGroup(self, ip, node):
>> diff --git a/lib/query.py b/lib/query.py
>> index ef52d08..a9e0274 100644
>> --- a/lib/query.py
>> +++ b/lib/query.py
>> @@ -90,7 +90,8 @@ from ganeti.constants import (QFT_UNKNOWN, QFT_TEXT,
>> QFT_BOOL, QFT_NUMBER,
>>   IQ_LIVE,
>>   IQ_DISKUSAGE,
>>   IQ_CONSOLE,
>> - IQ_NODES) = range(100, 105)
>> + IQ_NODES,
>> + IQ_NETWORKS) = range(100, 106)
>>
>>  (LQ_MODE,
>>   LQ_OWNER,
>> @@ -1383,7 +1384,7 @@ class InstanceQueryData:
>>
>>    """
>>    def __init__(self, instances, cluster, disk_usage, offline_nodes,
>> bad_nodes,
>> -               live_data, wrongnode_inst, console, nodes, groups):
>> +               live_data, wrongnode_inst, console, nodes, groups,
>> networks):
>>      """Initializes this class.
>>
>>      @param instances: List of instance objects
>> @@ -1402,6 +1403,8 @@ class InstanceQueryData:
>>      @param console: Per-instance console information
>>      @type nodes: dict; node name as key
>>      @param nodes: Node objects
>> +    @type networks: dict; net_uuid as key
>> +    @param networks: Network objects
>>
>>      """
>>      assert len(set(bad_nodes) & set(offline_nodes)) ==
>> len(offline_nodes), \
>> @@ -1419,6 +1422,7 @@ class InstanceQueryData:
>>      self.console = console
>>      self.nodes = nodes
>>      self.groups = groups
>> +    self.networks = networks
>>
>>      # Used for individual rows
>>      self.inst_hvparams = None
>> @@ -1569,6 +1573,20 @@ def _GetInstNic(index, cb):
>>    return fn
>>
>>
>> +def _GetInstNicNetworkName(ctx, _, nic): # pylint: disable=W0613
>> +  """Get a NIC's Network.
>> +
>> +  @type ctx: L{InstanceQueryData}
>> +  @type nic: L{objects.NIC}
>> +  @param nic: NIC object
>> +
>> +  """
>> +  if nic.network is None:
>> +    return _FS_UNAVAIL
>> +  else:
>> +    return ctx.networks[nic.network].name
>> +
>> +
>>  def _GetInstNicNetwork(ctx, _, nic): # pylint: disable=W0613
>>    """Get a NIC's Network.
>>
>> @@ -1615,6 +1633,27 @@ def _GetInstNicBridge(ctx, index, _):
>>      return _FS_UNAVAIL
>>
>>
>> +def _GetInstAllNicNetworkNames(ctx, inst):
>> +  """Get all network names for an instance.
>> +
>> +  @type ctx: L{InstanceQueryData}
>> +  @type inst: L{objects.Instance}
>> +  @param inst: Instance object
>> +
>> +  """
>> +  result = []
>> +
>> +  for nic in inst.nics:
>> +    name = None
>> +    if nic.network:
>> +      name = ctx.networks[nic.network].name
>> +    result.append(name)
>> +
>> +  assert len(result) == len(inst.nics)
>> +
>> +  return result
>> +
>> +
>>  def _GetInstAllNicBridges(ctx, inst):
>>    """Get all network bridges for an instance.
>>
>> @@ -1697,6 +1736,9 @@ def _GetInstanceNetworkFields():
>>      (_MakeField("nic.networks", "NIC_networks", QFT_OTHER,
>>                  "List containing each interface's network"), IQ_CONFIG,
>> 0,
>>       lambda ctx, inst: [nic.network for nic in inst.nics]),
>> +    (_MakeField("nic.networks.names", "NIC_networks_names", QFT_OTHER,
>> +                "List containing each interface's network"),
>> +     IQ_NETWORKS, 0, _GetInstAllNicNetworkNames)
>>      ]
>>
>>    # NICs by number
>> @@ -1721,6 +1763,9 @@ def _GetInstanceNetworkFields():
>>        (_MakeField("nic.network/%s" % i, "NicNetwork/%s" % i, QFT_TEXT,
>>                    "Network of %s network interface" % numtext),
>>         IQ_CONFIG, 0, _GetInstNic(i, _GetInstNicNetwork)),
>> +      (_MakeField("nic.network.name/%s" % i, "NicNetworkName/%s" % i,
>> QFT_TEXT,
>> +                  "Network name of %s network interface" % numtext),
>> +       IQ_NETWORKS, 0, _GetInstNic(i, _GetInstNicNetworkName)),
>>        ])
>>
>>    aliases = [
>> --
>> 1.7.10.4
>>
>



--
Guido Trotter
Ganeti engineering
Google Germany

Reply via email to