xenserver: Allow fail_mode to be set from xapi.
authorEthan Jackson <ethan@nicira.com>
Sat, 15 Jan 2011 01:10:55 +0000 (17:10 -0800)
committerEthan Jackson <ethan@nicira.com>
Tue, 18 Jan 2011 22:57:08 +0000 (14:57 -0800)
This commit allows xapi to set the fail mode through the
vswitch-controller-fail-mode other-config setting in the Pool
object.

Signed-off-by: Ethan Jackson <ethan@nicira.com>
xenserver/etc_xapi.d_plugins_openvswitch-cfg-update
xenserver/opt_xensource_libexec_InterfaceReconfigure.py
xenserver/opt_xensource_libexec_InterfaceReconfigureVswitch.py

index 7333018..a4d97f5 100755 (executable)
@@ -4,7 +4,7 @@
 # ovs-vswitchd configuration that are managed in the xapi database when 
 # integrated with Citrix management tools.
 
-# Copyright (C) 2009, 2010 Nicira Networks, Inc.
+# Copyright (C) 2009, 2010, 2011 Nicira Networks, Inc.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -64,6 +64,7 @@ def update(session, args):
             controller = pool["other_config"]["vSwitchController"]
     except KeyError, e:
         controller = ""
+    ret_str = ""
     currentController = vswitchCurrentController()
     if controller == "" and currentController != "":
         delete_cacert()
@@ -72,7 +73,7 @@ def update(session, args):
         except:
             pass
         removeControllerCfg()
-        return "Successfully removed controller config"
+        ret_str += "Successfully removed controller config.  "
     elif controller != currentController:
         delete_cacert()
         try:
@@ -80,7 +81,39 @@ def update(session, args):
         except:
             pass
         setControllerCfg(controller)
-        return "Successfully set controller to " + controller
+        ret_str += "Successfully set controller to %s.  " % controller
+
+    try:
+        fail_mode = pool["other_config"]["vswitch-controller-fail-mode"]
+    except KeyError, e:
+        fail_mode = None
+
+    if fail_mode != 'secure':
+        fail_mode = 'standalone'
+
+    fail_mode_changed = False
+    for (p, rec) in session.xenapi.PIF.get_all_records().items():
+        try:
+            network = session.xenapi.network.get_record(rec['network'])
+            bridge = network['bridge']
+        except Exception, e:
+            syslog.syslog("%s: failed to get bridge name (%s)" %
+                    (script, str(e)))
+            continue
+
+        bridge_fail_mode = vswitchCfgQuery(["get", "Bridge",
+            bridge, "fail_mode"]).strip('[]"')
+
+        if bridge_fail_mode != fail_mode:
+            vswitchCfgMod(['--', 'set', 'Bridge', bridge,
+                "fail_mode=%s" % fail_mode])
+            fail_mode_changed = True
+
+    if fail_mode_changed:
+        ret_str += "Set fail_mode to %s.  " % fail_mode
+
+    if ret_str != '':
+        return ret_str
     else:
         return "No change to configuration"
 
index 7204032..6cf19ee 100644 (file)
@@ -277,6 +277,7 @@ _VLAN_XML_TAG = "vlan"
 _TUNNEL_XML_TAG = "tunnel"
 _BOND_XML_TAG = "bond"
 _NETWORK_XML_TAG = "network"
+_POOL_XML_TAG = "pool"
 
 _ETHTOOL_OTHERCONFIG_ATTRS = ['ethtool-%s' % x for x in 'autoneg', 'speed', 'duplex', 'rx', 'tx', 'sg', 'tso', 'ufo', 'gso' ]
 
@@ -341,6 +342,12 @@ _NETWORK_ATTRS = { 'uuid': (_str_to_xml,_str_from_xml),
                                     lambda n: _otherconfig_from_xml(n, _NETWORK_OTHERCONFIG_ATTRS)),
                  }
 
+_POOL_OTHERCONFIG_ATTRS = ['vswitch-controller-fail-mode']
+
+_POOL_ATTRS = { 'other_config': (lambda x, p, t, v: _otherconfig_to_xml(x, p, v, _POOL_OTHERCONFIG_ATTRS),
+                                 lambda n: _otherconfig_from_xml(n, _POOL_OTHERCONFIG_ATTRS)),
+              }
+
 #
 # Database Cache object
 #
@@ -444,6 +451,20 @@ class DatabaseCache(object):
                 if not rec['other_config'].has_key(f): continue
                 self.__networks[n]['other_config'][f] = rec['other_config'][f]
 
+    def __get_pool_records_from_xapi(self, session):
+        self.__pools = {}
+        for p in session.xenapi.pool.get_all():
+            rec = session.xenapi.pool.get_record(p)
+
+            self.__pools[p] = {}
+
+            for f in _POOL_ATTRS:
+                self.__pools[p][f] = rec[f]
+
+            for f in _POOL_OTHERCONFIG_ATTRS:
+                if rec['other_config'].has_key(f):
+                    self.__pools[p]['other_config'][f] = rec['other_config'][f]
+
     def __to_xml(self, xml, parent, key, ref, rec, attrs):
         """Encode a database object as XML"""
         e = xml.createElement(key)
@@ -497,6 +518,7 @@ class DatabaseCache(object):
                     if error == "MESSAGE_METHOD_UNKNOWN" and details == "tunnel.get_all":
                         pass
 
+                self.__get_pool_records_from_xapi(session)
                 self.__get_vlan_records_from_xapi(session)
                 self.__get_bond_records_from_xapi(session)
                 self.__get_network_records_from_xapi(session)
@@ -511,6 +533,7 @@ class DatabaseCache(object):
             self.__pifs = {}
             self.__bonds = {}
             self.__vlans = {}
+            self.__pools = {}
             self.__tunnels = {}
             self.__networks = {}
 
@@ -537,6 +560,9 @@ class DatabaseCache(object):
                 elif n.nodeName == _NETWORK_XML_TAG:
                     (ref,rec) = self.__from_xml(n, _NETWORK_ATTRS)
                     self.__networks[ref] = rec
+                elif n.nodeName == _POOL_XML_TAG:
+                    (ref,rec) = self.__from_xml(n, _POOL_ATTRS)
+                    self.__pools[ref] = rec
                 else:
                     raise Error("Unknown XML element %s" % n.nodeName)
 
@@ -555,6 +581,8 @@ class DatabaseCache(object):
         for (ref,rec) in self.__networks.items():
             self.__to_xml(xml, xml.documentElement, _NETWORK_XML_TAG, ref, rec,
                           _NETWORK_ATTRS)
+        for (ref,rec) in self.__pools.items():
+            self.__to_xml(xml, xml.documentElement, _POOL_XML_TAG, ref, rec, _POOL_ATTRS)
 
         f = open(cache_file, 'w')
         f.write(xml.toprettyxml())
@@ -630,6 +658,9 @@ class DatabaseCache(object):
         else:
             return None
 
+    def get_pool_record(self):
+        return self.__pools.values()[0]
+
 #
 #
 #
index 5be7461..8429358 100644 (file)
@@ -331,6 +331,12 @@ def configure_datapath(pif):
     vsctl_argv += ['--', 'set', 'Bridge', bridge,
                    'other-config:hwaddr=%s' % vsctl_escape(db().get_pif_record(pif)['MAC'])]
 
+    pool = db().get_pool_record()
+    fail_mode = pool['other_config']['vswitch-controller-fail-mode']
+
+    if fail_mode in ['standalone', 'secure']:
+        vsctl_argv += ['--', 'set', 'Bridge', bridge, 'fail_mode=%s' % fail_mode]
+
     vsctl_argv += set_br_external_ids(pif)
     vsctl_argv += ['## done configuring datapath %s' % bridge]