From d89168ffd5c5519c66f37e713bcfbc98c2b4e454 Mon Sep 17 00:00:00 2001
From: Guido Trotter <ultrotter@google.com>
Date: Thu, 7 Feb 2013 14:30:38 +0100
Subject: [PATCH] OS environment: add network information

1) Move the hooks environment dict generator inside the object. This
also adds missing values such as network family and uuid.
2) Use the same generator both for the os environment and for the
instance hooks.
3) Update manpage and hooks documentation.

Also update a forgotten docstring about a tuple's content.

Signed-off-by: Guido Trotter <ultrotter@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 doc/hooks.rst               | 10 ++++++----
 lib/backend.py              | 10 ++++++++--
 lib/cmdlib.py               | 26 ++++++++------------------
 lib/objects.py              | 28 ++++++++++++++++++++++++++++
 man/ganeti-os-interface.rst | 33 +++++++++++++++++++++++++++++++++
 5 files changed, 83 insertions(+), 24 deletions(-)

diff --git a/doc/hooks.rst b/doc/hooks.rst
index faf10b82d..a9f073e2f 100644
--- a/doc/hooks.rst
+++ b/doc/hooks.rst
@@ -286,10 +286,12 @@ INSTANCE_NAME, INSTANCE_PRIMARY, INSTANCE_SECONDARY,
 INSTANCE_OS_TYPE, INSTANCE_DISK_TEMPLATE, INSTANCE_MEMORY,
 INSTANCE_DISK_SIZES, INSTANCE_VCPUS, INSTANCE_NIC_COUNT,
 INSTANCE_NICn_IP, INSTANCE_NICn_BRIDGE, INSTANCE_NICn_MAC,
-INSTANCE_NICn_NETWORK_SUBNET, INSTANCE_NICn_NETWORK_GATEWAY,
-INSTANCE_NICn_NETWORK_SUBNET6, INSTANCE_NICn_NETWORK_GATEWAY6,
-INSTANCE_NICn_NETWORK_MAC_PREFIX, INSTANCE_NICn_NETWORK_TYPE,
-INSTANCE_DISK_COUNT, INSTANCE_DISKn_SIZE, INSTANCE_DISKn_MODE.
+INSTANCE_NICn_NETWORK, INSTANCE_NICn_NETWORK_FAMILY,
+INSTANCE_NICn_NETWORK_UUID, INSTANCE_NICn_NETWORK_SUBNET,
+INSTANCE_NICn_NETWORK_GATEWAY, INSTANCE_NICn_NETWORK_SUBNET6,
+INSTANCE_NICn_NETWORK_GATEWAY6, INSTANCE_NICn_NETWORK_MAC_PREFIX,
+INSTANCE_NICn_NETWORK_TYPE, INSTANCE_DISK_COUNT, INSTANCE_DISKn_SIZE,
+INSTANCE_DISKn_MODE.
 
 The INSTANCE_NICn_* and INSTANCE_DISKn_* variables represent the
 properties of the *n* -th NIC and disk, and are zero-indexed.
diff --git a/lib/backend.py b/lib/backend.py
index b6918c87f..b7dd2ab3a 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -2498,8 +2498,14 @@ def OSEnvironment(instance, inst_os, debug=0):
       result["NIC_%d_BRIDGE" % idx] = nic.nicparams[constants.NIC_LINK]
     if nic.nicparams[constants.NIC_LINK]:
       result["NIC_%d_LINK" % idx] = nic.nicparams[constants.NIC_LINK]
-    if nic.network:
-      result["NIC_%d_NETWORK" % idx] = nic.network
+    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/cmdlib.py b/lib/cmdlib.py
index d14bb65e0..5ddecffcf 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -1453,7 +1453,7 @@ def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status,
   @type vcpus: string
   @param vcpus: the count of VCPUs the instance has
   @type nics: list
-  @param nics: list of tuples (ip, mac, mode, link, network) representing
+  @param nics: list of tuples (ip, mac, mode, link, net, netinfo) representing
       the NICs the instance has
   @type disk_template: string
   @param disk_template: the disk template of the instance
@@ -1495,24 +1495,14 @@ def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status,
       env["INSTANCE_NIC%d_MAC" % idx] = mac
       env["INSTANCE_NIC%d_MODE" % idx] = mode
       env["INSTANCE_NIC%d_LINK" % idx] = link
-      if network:
+      if netinfo:
+        nobj = objects.Network.FromDict(netinfo)
+        env.update(nobj.HooksDict("INSTANCE_NIC%d_" % idx))
+      elif 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.
         env["INSTANCE_NIC%d_NETWORK" % idx] = net
-        if netinfo:
-          nobj = objects.Network.FromDict(netinfo)
-          if nobj.network:
-            env["INSTANCE_NIC%d_NETWORK_SUBNET" % idx] = nobj.network
-          if nobj.gateway:
-            env["INSTANCE_NIC%d_NETWORK_GATEWAY" % idx] = nobj.gateway
-          if nobj.network6:
-            env["INSTANCE_NIC%d_NETWORK_SUBNET6" % idx] = nobj.network6
-          if nobj.gateway6:
-            env["INSTANCE_NIC%d_NETWORK_GATEWAY6" % idx] = nobj.gateway6
-          if nobj.mac_prefix:
-            env["INSTANCE_NIC%d_NETWORK_MAC_PREFIX" % idx] = nobj.mac_prefix
-          if nobj.network_type:
-            env["INSTANCE_NIC%d_NETWORK_TYPE" % idx] = nobj.network_type
-          if nobj.tags:
-            env["INSTANCE_NIC%d_NETWORK_TAGS" % idx] = " ".join(nobj.tags)
       if mode == constants.NIC_MODE_BRIDGED:
         env["INSTANCE_NIC%d_BRIDGE" % idx] = link
   else:
diff --git a/lib/objects.py b/lib/objects.py
index e3ff4ac4e..60f6afcc3 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -2039,6 +2039,34 @@ class Network(TaggableObject):
     "ext_reservations",
     ] + _TIMESTAMPS + _UUID
 
+  def HooksDict(self, prefix):
+    """Export a dictionary used by hooks with a network's information.
+
+    @type prefix: String
+    @param prefix: Prefix to prepend to the dict entries
+
+    """
+    result = {
+      "%sNETWORK" % prefix: self.name,
+      "%sNETWORK_UUID" % prefix: self.uuid,
+      "%sNETWORK_FAMILY" % prefix: str(self.family),
+      "%sNETWORK_TAGS" % prefix: " ".join(self.tags),
+    }
+    if self.network:
+      result["%sNETWORK_SUBNET" % prefix] = self.network
+    if self.gateway:
+      result["%sNETWORK_GATEWAY" % prefix] = self.gateway
+    if self.network6:
+      result["%sNETWORK_SUBNET6" % prefix] = self.network6
+    if self.gateway6:
+      result["%sNETWORK_GATEWAY6" % prefix] = self.gateway6
+    if self.mac_prefix:
+      result["%sNETWORK_MAC_PREFIX" % prefix] = self.mac_prefix
+    if self.network_type:
+      result["%sNETWORK_TYPE" % prefix] = self.network_type
+
+    return result
+
 
 class SerializableConfigParser(ConfigParser.SafeConfigParser):
   """Simple wrapper over ConfigParse that allows serialization.
diff --git a/man/ganeti-os-interface.rst b/man/ganeti-os-interface.rst
index 2e44021ff..cd7c763fc 100644
--- a/man/ganeti-os-interface.rst
+++ b/man/ganeti-os-interface.rst
@@ -118,6 +118,39 @@ NIC_%N_FRONTEND_TYPE
     instance, this can be one of: ``rtl8139``, ``ne2k_pci``,
     ``ne2k_isa``, ``paravirtual``.
 
+NIC_%d_NETWORK
+    (Optional) If a NIC network is specified, the network's name.
+
+NIC_%d_NETWORK_UUID
+    (Optional) If a NIC network is specified, the network's uuid.
+
+NIC_%d_NETWORK_FAMILY
+    (Optional) If a NIC network is specified, the network's family.
+
+NIC_%d_NETWORK_SUBNET
+    (Optional) If a NIC network is specified, the network's IPv4 subnet.
+
+NIC_%d_NETWORK_GATEWAY
+    (Optional) If a NIC network is specified, the network's IPv4
+    gateway.
+
+NIC_%d_NETWORK_SUBNET6
+    (Optional) If a NIC network is specified, the network's IPv6 subnet.
+
+NIC_%d_NETWORK_GATEWAY6
+    (Optional) If a NIC network is specified, the network's IPv6
+    gateway.
+
+NIC_%d_NETWORK_MAC_PREFIX
+    (Optional) If a NIC network is specified, the network's mac prefix.
+
+NIC_%d_NETWORK_TYPE
+    (Optional) If a NIC network is specified, the network's type.
+
+NIC_%d_NETWORK_TAGS
+    (Optional) If a NIC network is specified, the network's tags, space
+    separated.
+
 OSP_*name*
     Each OS parameter (see below) will be exported in its own
     variable, prefixed with ``OSP_``, and upper-cased. For example, a
-- 
GitLab