[PATCH devel-2.7 01/10] Make network config methods take uuid as argument

6 views
Skip to first unread message

Dimitris Aragiorgis

unread,
Feb 16, 2013, 8:19:31 AM2/16/13
to ganeti...@googlegroups.com, synnef...@googlegroups.com
This will be needed in the following patches where nic.network
will refer to network's uuid and not name.

Signed-off-by: Dimitris Aragiorgis <dim...@grnet.gr>
---
lib/config.py | 35 ++++++++++++++++-------------------
1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/lib/config.py b/lib/config.py
index 4f8c36d..532a762 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):
@@ -2526,20 +2524,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
+ @type net_uuid: string
+ @param net_uuid: 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 +2544,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):
--
1.7.10.4

Dimitris Aragiorgis

unread,
Feb 16, 2013, 8:19:33 AM2/16/13
to ganeti...@googlegroups.com, synnef...@googlegroups.com
This will be needed for Instance Queries. It walks through the
instance's NICs and returns a list network uuids that the NICs
are attached to.

Signed-off-by: Dimitris Aragiorgis <dim...@grnet.gr>
---
lib/config.py | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/lib/config.py b/lib/config.py
index 532a762..ee26de6 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -1572,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.

--
1.7.10.4

Dimitris Aragiorgis

unread,
Feb 16, 2013, 8:19:34 AM2/16/13
to ganeti...@googlegroups.com, synnef...@googlegroups.com
Make _InstanceQuery gather all network info related to instance's
NICs and in case of NETQ_INST in _NetworkQuery get all network
uuids directly from nic.network

Signed-off-by: Dimitris Aragiorgis <dim...@grnet.gr>
---
lib/cmdlib.py | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 9565684..394d94b 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -5860,10 +5860,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):
@@ -16543,8 +16550,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

@@ -16569,10 +16574,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:
--
1.7.10.4

Dimitris Aragiorgis

unread,
Feb 16, 2013, 8:19:35 AM2/16/13
to ganeti...@googlegroups.com, synnef...@googlegroups.com
Queries now return the network uuid as well as it's name. Here we
only use info provided be LUInstanceQueryData context.

Signed-off-by: Dimitris Aragiorgis <dim...@grnet.gr>
---
lib/query.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)

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

Dimitris Aragiorgis

unread,
Feb 16, 2013, 8:19:30 AM2/16/13
to ganeti...@googlegroups.com, synnef...@googlegroups.com
Hello,

This patch set splits the patch
"Store network's uuid and not name in nic.network"
I submitted few days ago. This one has no additions compared to
the previous one which got a LGTM.

Hope it makes the reviewing/merging process easier.

Thanks,
dimara

Dimitris Aragiorgis

unread,
Feb 16, 2013, 8:19:38 AM2/16/13
to ganeti...@googlegroups.com, synnef...@googlegroups.com
This was before the case too. Now is bit trickier because nic.network
is uuid. Info must derive from nic.netinfo.
---
lib/client/gnt_instance.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

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")

--
1.7.10.4

Dimitris Aragiorgis

unread,
Feb 16, 2013, 8:19:32 AM2/16/13
to ganeti...@googlegroups.com, synnef...@googlegroups.com
Refactor Instance related LUs to support nic.network as
a uuid. This removes all the unnecessary invocations to
LookupNetwork().

Signed-off-by: Dimitris Aragiorgis <dim...@grnet.gr>
---
lib/cmdlib.py | 127 ++++++++++++++++++++++++++++++---------------------------
1 file changed, 68 insertions(+), 59 deletions(-)

diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 3637644..9565684 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)


@@ -9950,8 +9949,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 +10687,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 +10703,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
@@ -13381,7 +13382,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 +13392,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 +13445,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 +13454,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",
@@ -16795,7 +16804,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):
--
1.7.10.4

Dimitris Aragiorgis

unread,
Feb 16, 2013, 8:19:36 AM2/16/13
to ganeti...@googlegroups.com, synnef...@googlegroups.com
This is needed in case more info than each nic's network uuid is to
be returned. We need to lock networks to get valid data. For now
only the name is returned as an extra field. All other can be added
with trivial effort.
---
lib/cmdlib.py | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 394d94b..8ec5946 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -5751,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
@@ -5770,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))
@@ -12823,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
@@ -12841,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.

@@ -12850,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"
@@ -12861,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()

@@ -12945,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]

--
1.7.10.4

Dimitris Aragiorgis

unread,
Feb 16, 2013, 8:19:37 AM2/16/13
to ganeti...@googlegroups.com, synnef...@googlegroups.com
Signed-off-by: Dimitris Aragiorgis <dim...@grnet.gr>
---
test/py/ganeti.query_unittest.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/test/py/ganeti.query_unittest.py b/test/py/ganeti.query_unittest.py
index 024102a..e1b8600 100755
--- a/test/py/ganeti.query_unittest.py
+++ b/test/py/ganeti.query_unittest.py
@@ -617,7 +617,7 @@ class TestInstanceQuery(unittest.TestCase):
]

iqd = query.InstanceQueryData(instances, cluster, None, [], [], {},
- set(), {}, None, None)
+ set(), {}, None, None, None)
self.assertEqual(q.Query(iqd),
[[(constants.RS_NORMAL, "inst1"),
(constants.RS_NORMAL, 128),
@@ -646,7 +646,7 @@ class TestInstanceQuery(unittest.TestCase):
q = self._Create(selected)
self.assertEqual(q.RequestedData(),
set([query.IQ_CONFIG, query.IQ_LIVE, query.IQ_DISKUSAGE,
- query.IQ_CONSOLE, query.IQ_NODES]))
+ query.IQ_CONSOLE, query.IQ_NODES, query.IQ_NETWORKS]))

cluster = objects.Cluster(cluster_name="testcluster",
hvparams=constants.HVC_DEFAULTS,
@@ -823,7 +823,7 @@ class TestInstanceQuery(unittest.TestCase):

iqd = query.InstanceQueryData(instances, cluster, disk_usage,
offline_nodes, bad_nodes, live_data,
- wrongnode_inst, consinfo, {}, {})
+ wrongnode_inst, consinfo, {}, {}, {})
result = q.Query(iqd)
self.assertEqual(len(result), len(instances))
self.assert_(compat.all(len(row) == len(selected)
--
1.7.10.4

Dimitris Aragiorgis

unread,
Feb 16, 2013, 8:19:39 AM2/16/13
to ganeti...@googlegroups.com, synnef...@googlegroups.com
In backend NICs arrive with netinfo filled. If nic.network is not None
nic.netinfo is not too. Thus all the info is derived from HooksDict()
and nic.network must not be checked.
---
lib/backend.py | 5 -----
1 file changed, 5 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]
--
1.7.10.4

Dimitris Aragiorgis

unread,
Feb 16, 2013, 8:19:40 AM2/16/13
to ganeti...@googlegroups.com, synnef...@googlegroups.com
This gets all network info from config_data and parses
all instances and their NICs and makes the substitution.

Signed-off-by: Dimitris Aragiorgis <dim...@grnet.gr>
---
tools/cfgupgrade | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/tools/cfgupgrade b/tools/cfgupgrade
index bccb34e..d538284 100755
--- a/tools/cfgupgrade
+++ b/tools/cfgupgrade
@@ -110,6 +110,18 @@ def UpgradeGroups(config_data):
if not networks:
group["networks"] = {}

+def UpgradeInstances(config_data):
+ network2uuid = dict((n["name"], n["uuid"])
+ for n in config_data["networks"].values())
+ for inst in config_data["instances"].values():
+ for nic in inst["nics"]:
+ name = nic.get("network", None)
+ if name:
+ uuid = network2uuid.get(name, None)
+ if uuid:
+ print("NIC with network name %s found."
+ " Substituting with uuid %s." % (name, uuid))
+ nic["network"] = uuid

def main():
"""Main program.
@@ -294,6 +306,7 @@ def main():

UpgradeNetworks(config_data)
UpgradeGroups(config_data)
+ UpgradeInstances(config_data)

try:
logging.info("Writing configuration file to %s", options.CONFIG_DATA_PATH)
--
1.7.10.4

Helga Velroyen

unread,
Feb 18, 2013, 5:10:33 AM2/18/13
to Dimitris Aragiorgis, Ganeti Development, synnef...@googlegroups.com
Thanks for that! That makes it indeed easier to handle.

Helga Velroyen

unread,
Feb 18, 2013, 5:10:48 AM2/18/13
to Dimitris Aragiorgis, Ganeti Development, synnef...@googlegroups.com
LGTM


On Sat, Feb 16, 2013 at 2:19 PM, Dimitris Aragiorgis <dim...@grnet.gr> wrote:

Helga Velroyen

unread,
Feb 18, 2013, 5:11:05 AM2/18/13
to Dimitris Aragiorgis, Ganeti Development, synnef...@googlegroups.com
LGTM


On Sat, Feb 16, 2013 at 2:19 PM, Dimitris Aragiorgis <dim...@grnet.gr> wrote:

Helga Velroyen

unread,
Feb 18, 2013, 5:11:12 AM2/18/13
to Dimitris Aragiorgis, Ganeti Development, synnef...@googlegroups.com
LGTM


On Sat, Feb 16, 2013 at 2:19 PM, Dimitris Aragiorgis <dim...@grnet.gr> wrote:

Helga Velroyen

unread,
Feb 18, 2013, 5:11:23 AM2/18/13
to Dimitris Aragiorgis, Ganeti Development, synnef...@googlegroups.com
LGTM


On Sat, Feb 16, 2013 at 2:19 PM, Dimitris Aragiorgis <dim...@grnet.gr> wrote:

Helga Velroyen

unread,
Feb 18, 2013, 5:11:35 AM2/18/13
to Dimitris Aragiorgis, Ganeti Development, synnef...@googlegroups.com
LGTM


On Sat, Feb 16, 2013 at 2:19 PM, Dimitris Aragiorgis <dim...@grnet.gr> wrote:

Helga Velroyen

unread,
Feb 18, 2013, 5:11:45 AM2/18/13
to Dimitris Aragiorgis, Ganeti Development, synnef...@googlegroups.com
LGTM


On Sat, Feb 16, 2013 at 2:19 PM, Dimitris Aragiorgis <dim...@grnet.gr> wrote:

Helga Velroyen

unread,
Feb 18, 2013, 5:12:00 AM2/18/13
to Dimitris Aragiorgis, Ganeti Development, synnef...@googlegroups.com
LGTM


On Sat, Feb 16, 2013 at 2:19 PM, Dimitris Aragiorgis <dim...@grnet.gr> wrote:

Helga Velroyen

unread,
Feb 18, 2013, 5:12:08 AM2/18/13
to Dimitris Aragiorgis, Ganeti Development, synnef...@googlegroups.com
LGTM


On Sat, Feb 16, 2013 at 2:19 PM, Dimitris Aragiorgis <dim...@grnet.gr> wrote:

Helga Velroyen

unread,
Feb 18, 2013, 5:12:20 AM2/18/13
to Dimitris Aragiorgis, Ganeti Development, synnef...@googlegroups.com
LGTM


On Sat, Feb 16, 2013 at 2:19 PM, Dimitris Aragiorgis <dim...@grnet.gr> wrote:

Helga Velroyen

unread,
Feb 18, 2013, 5:12:55 AM2/18/13
to Dimitris Aragiorgis, Ganeti Development, synnef...@googlegroups.com
(Typo in the subject, will fix that before pushing.)

LGTM


On Sat, Feb 16, 2013 at 2:19 PM, Dimitris Aragiorgis <dim...@grnet.gr> wrote:
Reply all
Reply to author
Forward
0 new messages