xenserver: Drop "init-dbcache" by making PIF optional for "rewrite".
[openvswitch] / xenserver / opt_xensource_libexec_interface-reconfigure
index 61027c5fc886268868e3fdfc03813a431a6cde6f..27195ad93e69c60f3f59316edcf0de53cd77711f 100755 (executable)
@@ -5,22 +5,26 @@
 #
 """Usage:
 
-    %(command-name)s --session <SESSION-REF> --pif <PIF-REF> [up|down|rewrite]
-    %(command-name)s --force <BRIDGE> [up|down|rewrite <CONFIG>]
+    %(command-name)s <PIF> up
+    %(command-name)s <PIF> down
+    %(command-name)s [<PIF>] rewrite
+    %(command-name)s --force <BRIDGE> up
+    %(command-name)s --force <BRIDGE> down
+    %(command-name)s --force <BRIDGE> rewrite --device=<INTERFACE> <CONFIG>
     %(command-name)s --force all down
 
-    where,
-          <CONFIG> = --device=<INTERFACE> --mode=dhcp
-          <CONFIG> = --device=<INTERFACE> --mode=static --ip=<IPADDR> --netmask=<NM> [--gateway=<GW>]
+    where <PIF> is one of:
+       --session <SESSION-REF> --pif <PIF-REF>
+       --pif-uuid <PIF-UUID>
+    and <CONFIG> is one of:
+       --mode=dhcp
+       --mode=static --ip=<IPADDR> --netmask=<NM> [--gateway=<GW>]
 
   Options:
     --session          A session reference to use to access the xapi DB
-    --pif               A PIF reference.
-    --force-interface  An interface name. Mutually exclusive with --session/--pif.
-
-  Either both --session and --pif  or just --pif-uuid.
-  
-  <ACTION> is either "up" or "down" or "rewrite"
+    --pif               A PIF reference within the session.
+    --pif-uuid          The UUID of a PIF.
+    --force             An interface name.
 """
 
 #
@@ -28,7 +32,6 @@
 #
 #  --output-directory=<DIR>    Write configuration to <DIR>. Also disables actually
 #                               raising/lowering the interfaces
-#  --pif-uuid                  A PIF UUID, use instead of --session/--pif.
 #
 #
 #
 # 3. A network may have an associated bridge, allowing vifs to be attached
 # 4. A network may be bridgeless (there's no point having a bridge over a storage pif)
 
-# XXX: --force-interface=all down
-
-# XXX: --force-interface rewrite
-
-# XXX: Sometimes this leaves "orphaned" datapaths, e.g. a datapath whose
-#      only port is the local port.  Should delete those.
-
-# XXX: This can leave crud in ovs-vswitchd.conf in this scenario:
-#      - Create bond in XenCenter.
-#      - Create VLAN on bond in XenCenter.
-#      - Attempt to delete bond in XenCenter (this will fail because there
-#        is a VLAN on the bond, although the error may not be reported
-#        until the next step)
-#      - Delete VLAN in XenCenter.
-#      - Delete bond in XenCenter.
-# At this point there will still be some configuration data for the bond
-# or the VLAN in ovs-vswitchd.conf.
-
 import XenAPI
 import os, sys, getopt, time, signal
 import syslog
@@ -71,8 +56,8 @@ output_directory = None
 db = None
 management_pif = None
 
-dbcache_file = "/etc/ovs-vswitch.dbcache"
-vswitch_config_dir = "/etc/openvswitch"
+vswitch_state_dir = "/var/lib/openvswitch/"
+dbcache_file = vswitch_state_dir + "dbcache"
 
 class Usage(Exception):
     def __init__(self, msg):
@@ -370,6 +355,12 @@ PIF_ATTRS = { 'uuid': (str_to_xml,str_from_xml),
               'MAC': (str_to_xml,str_from_xml),
               'other_config': (lambda x, p, t, v: otherconfig_to_xml(x, p, v, PIF_OTHERCONFIG_ATTRS),
                                lambda n: otherconfig_from_xml(n, PIF_OTHERCONFIG_ATTRS)),
+              
+              # Special case: We write the current value
+              # PIF.currently-attached to the cache but since it will
+              # not be valid when we come to use the cache later
+              # (i.e. after a reboot) we always read it as False.
+              'currently_attached': (bool_to_xml, lambda n: False),
             }
 
 PIF_OTHERCONFIG_ATTRS = [ 'domain', 'peerdns', 'defaultroute', 'mtu', 'static-routes' ] + \
@@ -450,7 +441,11 @@ class DatabaseCache(object):
             rec = session.xenapi.network.get_record(n)
             self.__networks[n] = {}
             for f in NETWORK_ATTRS:
-                self.__networks[n][f] = rec[f]
+                if f == "PIFs":
+                    # drop PIFs on other hosts
+                    self.__networks[n][f] = [p for p in rec[f] if self.__pif_on_host(p)]
+                else:
+                    self.__networks[n][f] = rec[f]
             self.__networks[n]['other_config'] = {}
             for f in NETWORK_OTHERCONFIG_ATTRS:
                 if not rec['other_config'].has_key(f): continue
@@ -708,10 +703,7 @@ def log_pif_action(action, pif):
     rec['ip_configuration_mode'] = pifrec['ip_configuration_mode']
     rec['action'] = action
     rec['interface-name'] = interface_name(pif)
-    if action == "rewrite":
-        rec['message'] = "Rewrite PIF %(uuid)s configuration" % rec
-    else:
-        rec['message'] = "Bring %(action)s PIF %(uuid)s" % rec
+    rec['message'] = "Bring %(action)s PIF %(uuid)s" % rec
     log("%(message)s: %(interface-name)s configured as %(ip_configuration_mode)s" % rec)
 
 def get_bond_masters_of_pif(pif):
@@ -1038,7 +1030,7 @@ def configure_physdev(pif):
     run_ethtool(device, oc)
 
 def modify_config(commands):
-    run_command(['/root/vswitch/bin/ovs-cfg-mod', '-vANY:console:emer',
+    run_command(['/usr/bin/ovs-cfg-mod', '-vANY:console:emer',
                  '-F', '/etc/ovs-vswitchd.conf']
                 + commands + ['-c'])
     run_command(['/sbin/service', 'vswitch', 'reload'])
@@ -1131,9 +1123,9 @@ def action_up(pif):
 
     # /etc/xensource/scripts/vif needs to know where to add VIFs.
     if vlan_slave:
-        if not os.path.exists(vswitch_config_dir):
-            os.mkdir(vswitch_config_dir)
-        br = ConfigurationFile("br-%s" % bridge, vswitch_config_dir)
+        if not os.path.exists(vswitch_state_dir):
+            os.mkdir(vswitch_state_dir)
+        br = ConfigurationFile("br-%s" % bridge, vswitch_state_dir)
         br.write("VLAN_SLAVE=%s\n" % datapath)
         br.write("VLAN_VID=%s\n" % pifrec['VLAN'])
         br.close()
@@ -1198,7 +1190,7 @@ def action_up(pif):
     # - The networks corresponding to any VLANs attached to the
     #   datapath's PIF.
     network_uuids = []
-    for nwpif in db.get_pifs_by_device({'device': pifrec['device']}):
+    for nwpif in db.get_pifs_by_device(pifrec['device']):
         net = db.get_pif_record(nwpif)['network']
         network_uuids += [db.get_network_record(net)['uuid']]
 
@@ -1233,7 +1225,7 @@ def action_up(pif):
         argv += ['--add=iface.%s.fake-bridge=true' % (ipdev)]
     else:
         try:
-            os.unlink("%s/br-%s" % (vswitch_config_dir, bridge))
+            os.unlink("%s/br-%s" % (vswitch_state_dir, bridge))
         except OSError:
             pass
     argv += ['--del-match=bridge.%s.xs-network-uuids=*' % datapath]
@@ -1471,35 +1463,37 @@ def main(argv=None):
 
             if pif_uuid:
                 pif = db.get_pif_by_uuid(pif_uuid)
-        
-            if not pif:
-                raise Usage("No PIF given")
 
-            if force_management:
-                # pif is going to be the management pif 
-                management_pif = pif
+            if action == "rewrite" and not pif:
+                pass
             else:
-                # pif is not going to be the management pif.
-                # Search DB cache for pif on same host with management=true
-                pifrec = db.get_pif_record(pif)
-                management_pif = db.get_management_pif()
+                if not pif:
+                    raise Usage("No PIF given")
 
-            log_pif_action(action, pif)
+                if force_management:
+                    # pif is going to be the management pif 
+                    management_pif = pif
+                else:
+                    # pif is not going to be the management pif.
+                    # Search DB cache for pif on same host with management=true
+                    pifrec = db.get_pif_record(pif)
+                    management_pif = db.get_management_pif()
 
-            if not check_allowed(pif):
-                return 0
+                log_pif_action(action, pif)
 
-            if action == "up":
-                action_up(pif)
-            elif action == "down":
-                action_down(pif)
-            elif action == "rewrite":
-                action_rewrite(pif)
-            else:
-                raise Usage("Unknown action %s"  % action)
+                if not check_allowed(pif):
+                    return 0
+
+                if action == "up":
+                    action_up(pif)
+                elif action == "down":
+                    action_down(pif)
+                elif action == "rewrite":
+                    action_rewrite(pif)
+                else:
+                    raise Usage("Unknown action %s"  % action)
 
             # Save cache.
-            pifrec = db.get_pif_record(pif)
             db.save(dbcache_file)
         
     except Usage, err: