Merge "Make dependency on libvirt dynamic"
diff --git a/files/apts/general b/files/apts/general
index a1fcf3c..ec6dd0d 100644
--- a/files/apts/general
+++ b/files/apts/general
@@ -1,5 +1,4 @@
 bridge-utils
-pep8
 pylint
 python-pip
 screen
diff --git a/files/apts/horizon b/files/apts/horizon
index 2c2faf1..e1ce85f 100644
--- a/files/apts/horizon
+++ b/files/apts/horizon
@@ -11,7 +11,6 @@
 python-webob
 python-kombu
 pylint
-pep8
 python-eventlet
 python-nose
 python-sphinx
diff --git a/files/rpms-suse/general b/files/rpms-suse/general
index b8ceeb7..93711ff 100644
--- a/files/rpms-suse/general
+++ b/files/rpms-suse/general
@@ -8,7 +8,6 @@
 psmisc
 python-cmd2 # dist:opensuse-12.3
 python-netaddr
-python-pep8
 python-pip
 python-pylint
 python-unittest2
diff --git a/files/rpms-suse/horizon b/files/rpms-suse/horizon
index 7e46ffe..405fb7a 100644
--- a/files/rpms-suse/horizon
+++ b/files/rpms-suse/horizon
@@ -17,7 +17,6 @@
 python-mox
 python-netaddr
 python-nose
-python-pep8
 python-pylint
 python-sqlalchemy-migrate
 python-xattr
diff --git a/files/rpms/general b/files/rpms/general
index 764b602..d6abae9 100644
--- a/files/rpms/general
+++ b/files/rpms/general
@@ -11,7 +11,6 @@
 psmisc
 pylint
 python-netaddr
-python-pep8
 python-pip
 python-prettytable # dist:rhel6 [1]
 python-unittest2
@@ -29,4 +28,4 @@
 
 # [2] : RHEL6 rpm versions of python-lxml is old, and has to be
 # removed.  Several tools rely on it, so we install the dependencies
-# pip needs to build it here (see tools/install_prereqs.sh)
\ No newline at end of file
+# pip needs to build it here (see tools/install_prereqs.sh)
diff --git a/files/rpms/horizon b/files/rpms/horizon
index cf16cdb..e27888a 100644
--- a/files/rpms/horizon
+++ b/files/rpms/horizon
@@ -20,7 +20,6 @@
 python-nose
 python-paste        #dist:f16,f17,f18
 python-paste-deploy #dist:f16,f17,f18
-python-pep8
 python-routes
 python-sphinx
 python-sqlalchemy
diff --git a/lib/nova b/lib/nova
index ae9da23..508ed78 100644
--- a/lib/nova
+++ b/lib/nova
@@ -443,7 +443,7 @@
         iniset $NOVA_CONF DEFAULT libvirt_cpu_mode "none"
     fi
     iniset $NOVA_CONF DEFAULT instance_name_template "${INSTANCE_NAME_PREFIX}%08x"
-    iniset $NOVA_CONF DEFAULT osapi_v3_enabled "True"
+    iniset $NOVA_CONF osapi_v3 enabled "True"
 
     if is_fedora; then
         # nova defaults to /usr/local/bin, but fedora pip likes to
diff --git a/lib/quantum_plugins/linuxbridge b/lib/quantum_plugins/linuxbridge
index 980df5f..71832f1 100644
--- a/lib/quantum_plugins/linuxbridge
+++ b/lib/quantum_plugins/linuxbridge
@@ -5,19 +5,6 @@
 MY_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
-function is_quantum_ovs_base_plugin() {
-    # linuxbridge doesn't use OVS
-    return 1
-}
-
-function quantum_plugin_create_nova_conf() {
-    NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtGenericVIFDriver"}
-}
-
-function quantum_plugin_install_agent_packages() {
-    install_package bridge-utils
-}
-
 function quantum_plugin_configure_common() {
     Q_PLUGIN_CONF_PATH=etc/quantum/plugins/linuxbridge
     Q_PLUGIN_CONF_FILENAME=linuxbridge_conf.ini
@@ -25,37 +12,6 @@
     Q_PLUGIN_CLASS="quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2"
 }
 
-function quantum_plugin_configure_debug_command() {
-    iniset $QUANTUM_TEST_CONFIG_FILE DEFAULT external_network_bridge
-}
-
-function quantum_plugin_configure_dhcp_agent() {
-    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager quantum.agent.dhcp_agent.DhcpAgentWithStateReport
-}
-
-function quantum_plugin_configure_l3_agent() {
-    iniset $Q_L3_CONF_FILE DEFAULT external_network_bridge
-    iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager quantum.agent.l3_agent.L3NATAgentWithStateReport
-}
-
-function quantum_plugin_configure_plugin_agent() {
-    # Setup physical network interface mappings.  Override
-    # ``LB_VLAN_RANGES`` and ``LB_INTERFACE_MAPPINGS`` in ``localrc`` for more
-    # complex physical network configurations.
-    if [[ "$LB_INTERFACE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$LB_PHYSICAL_INTERFACE" != "" ]]; then
-        LB_INTERFACE_MAPPINGS=$PHYSICAL_NETWORK:$LB_PHYSICAL_INTERFACE
-    fi
-    if [[ "$LB_INTERFACE_MAPPINGS" != "" ]]; then
-        iniset /$Q_PLUGIN_CONF_FILE LINUX_BRIDGE physical_interface_mappings $LB_INTERFACE_MAPPINGS
-    fi
-    if [[ "$Q_USE_SECGROUP" == "True" ]]; then
-        iniset /$Q_PLUGIN_CONF_FILE SECURITYGROUP firewall_driver quantum.agent.linux.iptables_firewall.IptablesFirewallDriver
-    else
-        iniset /$Q_PLUGIN_CONF_FILE SECURITYGROUP firewall_driver quantum.agent.firewall.NoopFirewallDriver
-    fi
-    AGENT_BINARY="$QUANTUM_DIR/bin/quantum-linuxbridge-agent"
-}
-
 function quantum_plugin_configure_service() {
     if [[ "$ENABLE_TENANT_VLANS" = "True" ]]; then
         iniset /$Q_PLUGIN_CONF_FILE VLANS tenant_network_type vlan
@@ -81,19 +37,10 @@
     fi
 }
 
-function quantum_plugin_setup_interface_driver() {
-    local conf_file=$1
-    iniset $conf_file DEFAULT interface_driver quantum.agent.linux.interface.BridgeInterfaceDriver
-}
-
 function has_quantum_plugin_security_group() {
     # 0 means True here
     return 0
 }
 
-function quantum_plugin_check_adv_test_requirements() {
-    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
-}
-
 # Restore xtrace
 $MY_XTRACE
diff --git a/lib/quantum_plugins/linuxbridge_agent b/lib/quantum_plugins/linuxbridge_agent
new file mode 100644
index 0000000..1e83275
--- /dev/null
+++ b/lib/quantum_plugins/linuxbridge_agent
@@ -0,0 +1,62 @@
+# Quantum Linux Bridge L2 agent
+# -----------------------------
+
+# Save trace setting
+PLUGIN_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+function is_quantum_ovs_base_plugin() {
+    # linuxbridge doesn't use OVS
+    return 1
+}
+
+function quantum_plugin_create_nova_conf() {
+    NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtGenericVIFDriver"}
+}
+
+function quantum_plugin_install_agent_packages() {
+    install_package bridge-utils
+}
+
+function quantum_plugin_configure_debug_command() {
+    iniset $QUANTUM_TEST_CONFIG_FILE DEFAULT external_network_bridge
+}
+
+function quantum_plugin_configure_dhcp_agent() {
+    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager quantum.agent.dhcp_agent.DhcpAgentWithStateReport
+}
+
+function quantum_plugin_configure_l3_agent() {
+    iniset $Q_L3_CONF_FILE DEFAULT external_network_bridge
+    iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager quantum.agent.l3_agent.L3NATAgentWithStateReport
+}
+
+function quantum_plugin_configure_plugin_agent() {
+    # Setup physical network interface mappings.  Override
+    # ``LB_VLAN_RANGES`` and ``LB_INTERFACE_MAPPINGS`` in ``localrc`` for more
+    # complex physical network configurations.
+    if [[ "$LB_INTERFACE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$LB_PHYSICAL_INTERFACE" != "" ]]; then
+        LB_INTERFACE_MAPPINGS=$PHYSICAL_NETWORK:$LB_PHYSICAL_INTERFACE
+    fi
+    if [[ "$LB_INTERFACE_MAPPINGS" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE LINUX_BRIDGE physical_interface_mappings $LB_INTERFACE_MAPPINGS
+    fi
+    if [[ "$Q_USE_SECGROUP" == "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE SECURITYGROUP firewall_driver quantum.agent.linux.iptables_firewall.IptablesFirewallDriver
+    else
+        iniset /$Q_PLUGIN_CONF_FILE SECURITYGROUP firewall_driver quantum.agent.firewall.NoopFirewallDriver
+    fi
+    AGENT_BINARY="$QUANTUM_DIR/bin/quantum-linuxbridge-agent"
+}
+
+function quantum_plugin_setup_interface_driver() {
+    local conf_file=$1
+    iniset $conf_file DEFAULT interface_driver quantum.agent.linux.interface.BridgeInterfaceDriver
+}
+
+function quantum_plugin_check_adv_test_requirements() {
+    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
+}
+
+# Restore xtrace
+$PLUGIN_XTRACE
diff --git a/lib/quantum_plugins/ml2 b/lib/quantum_plugins/ml2
new file mode 100644
index 0000000..ae8fe6c
--- /dev/null
+++ b/lib/quantum_plugins/ml2
@@ -0,0 +1,62 @@
+# Quantum Modular Layer 2 plugin
+# ------------------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+# Default openvswitch L2 agent
+Q_AGENT=${Q_AGENT:-openvswitch}
+source $TOP_DIR/lib/quantum_plugins/${Q_AGENT}_agent
+
+function quantum_plugin_configure_common() {
+    Q_PLUGIN_CONF_PATH=etc/quantum/plugins/ml2
+    Q_PLUGIN_CONF_FILENAME=ml2_conf.ini
+    Q_DB_NAME="quantum_ml2"
+    Q_PLUGIN_CLASS="quantum.plugins.ml2.plugin.Ml2Plugin"
+}
+
+function quantum_plugin_configure_service() {
+    if [[ "$ENABLE_TENANT_TUNNELS" = "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE ml2 tenant_network_types gre
+        iniset /$Q_PLUGIN_CONF_FILE ml2_type_gre tunnel_id_ranges $TENANT_TUNNEL_RANGES
+    elif [[ "$ENABLE_TENANT_VLANS" = "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE ml2 tenant_network_types vlan
+    else
+        echo "WARNING - The ml2 plugin is using local tenant networks, with no connectivity between hosts."
+    fi
+
+    # Override ``ML2_VLAN_RANGES`` and any needed agent configuration
+    # variables in ``localrc`` for more complex physical network
+    # configurations.
+    if [[ "$ML2_VLAN_RANGES" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
+        ML2_VLAN_RANGES=$PHYSICAL_NETWORK
+        if [[ "$TENANT_VLAN_RANGE" != "" ]]; then
+            ML2_VLAN_RANGES=$ML2_VLAN_RANGES:$TENANT_VLAN_RANGE
+        fi
+    fi
+    if [[ "$ML2_VLAN_RANGES" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE ml2_type_vlan network_vlan_ranges $ML2_VLAN_RANGES
+    fi
+
+    # REVISIT(rkukura): Setting firewall_driver here for
+    # quantum.agent.securitygroups_rpc.is_firewall_enabled() which is
+    # used in the server, in case no L2 agent is configured on the
+    # server's node. If an L2 agent is configured, this will get
+    # overridden with the correct driver. The ml2 plugin should
+    # instead use its own config variable to indicate whether security
+    # groups is enabled, and that will need to be set here instead.
+    if [[ "$Q_USE_SECGROUP" == "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE SECURITYGROUP firewall_driver quantum.agent.not.a.real.FirewallDriver
+    else
+        iniset /$Q_PLUGIN_CONF_FILE SECURITYGROUP firewall_driver quantum.agent.firewall.NoopFirewallDriver
+    fi
+
+}
+
+function has_quantum_plugin_security_group() {
+    return 0
+}
+
+# Restore xtrace
+$MY_XTRACE
diff --git a/lib/quantum_plugins/openvswitch b/lib/quantum_plugins/openvswitch
index d5d4f10..cd29c19 100644
--- a/lib/quantum_plugins/openvswitch
+++ b/lib/quantum_plugins/openvswitch
@@ -1,25 +1,11 @@
-# Quantum Open vSwtich plugin
+# Quantum Open vSwitch plugin
 # ---------------------------
 
 # Save trace setting
 MY_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
-source $TOP_DIR/lib/quantum_plugins/ovs_base
-
-function quantum_plugin_create_nova_conf() {
-    _quantum_ovs_base_configure_nova_vif_driver
-    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
-        iniset $NOVA_CONF DEFAULT xenapi_vif_driver nova.virt.xenapi.vif.XenAPIOpenVswitchDriver
-        iniset $NOVA_CONF DEFAULT xenapi_ovs_integration_bridge $XEN_INTEGRATION_BRIDGE
-        # Disable nova's firewall so that it does not conflict with quantum
-        iniset $NOVA_CONF DEFAULT firewall_driver nova.virt.firewall.NoopFirewallDriver
-    fi
-}
-
-function quantum_plugin_install_agent_packages() {
-    _quantum_ovs_base_install_agent_packages
-}
+source $TOP_DIR/lib/quantum_plugins/openvswitch_agent
 
 function quantum_plugin_configure_common() {
     Q_PLUGIN_CONF_PATH=etc/quantum/plugins/openvswitch
@@ -28,89 +14,6 @@
     Q_PLUGIN_CLASS="quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2"
 }
 
-function quantum_plugin_configure_debug_command() {
-    _quantum_ovs_base_configure_debug_command
-}
-
-function quantum_plugin_configure_dhcp_agent() {
-    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager quantum.agent.dhcp_agent.DhcpAgentWithStateReport
-}
-
-function quantum_plugin_configure_l3_agent() {
-    _quantum_ovs_base_configure_l3_agent
-    iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager quantum.agent.l3_agent.L3NATAgentWithStateReport
-}
-
-function quantum_plugin_configure_plugin_agent() {
-    # Setup integration bridge
-    _quantum_ovs_base_setup_bridge $OVS_BRIDGE
-    _quantum_ovs_base_configure_firewall_driver
-
-    # Setup agent for tunneling
-    if [[ "$OVS_ENABLE_TUNNELING" = "True" ]]; then
-        # Verify tunnels are supported
-        # REVISIT - also check kernel module support for GRE and patch ports
-        OVS_VERSION=`ovs-vsctl --version | head -n 1 | awk '{print $4;}'`
-        if [ $OVS_VERSION \< "1.4" ] && ! is_service_enabled q-svc ; then
-            die $LINENO "You are running OVS version $OVS_VERSION. OVS 1.4+ is required for tunneling between multiple hosts."
-        fi
-        iniset /$Q_PLUGIN_CONF_FILE OVS enable_tunneling True
-        iniset /$Q_PLUGIN_CONF_FILE OVS local_ip $HOST_IP
-    fi
-
-    # Setup physical network bridge mappings.  Override
-    # ``OVS_VLAN_RANGES`` and ``OVS_BRIDGE_MAPPINGS`` in ``localrc`` for more
-    # complex physical network configurations.
-    if [[ "$OVS_BRIDGE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$OVS_PHYSICAL_BRIDGE" != "" ]]; then
-        OVS_BRIDGE_MAPPINGS=$PHYSICAL_NETWORK:$OVS_PHYSICAL_BRIDGE
-
-        # Configure bridge manually with physical interface as port for multi-node
-        sudo ovs-vsctl --no-wait -- --may-exist add-br $OVS_PHYSICAL_BRIDGE
-    fi
-    if [[ "$OVS_BRIDGE_MAPPINGS" != "" ]]; then
-        iniset /$Q_PLUGIN_CONF_FILE OVS bridge_mappings $OVS_BRIDGE_MAPPINGS
-    fi
-    AGENT_BINARY="$QUANTUM_DIR/bin/quantum-openvswitch-agent"
-
-    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
-        # Make a copy of our config for domU
-        sudo cp /$Q_PLUGIN_CONF_FILE "/$Q_PLUGIN_CONF_FILE.domu"
-
-        # Deal with Dom0's L2 Agent:
-        Q_RR_DOM0_COMMAND="$QUANTUM_DIR/bin/quantum-rootwrap-xen-dom0 $Q_RR_CONF_FILE"
-
-        # For now, duplicate the xen configuration already found in nova.conf
-        iniset $Q_RR_CONF_FILE XENAPI xenapi_connection_url "$XENAPI_CONNECTION_URL"
-        iniset $Q_RR_CONF_FILE XENAPI xenapi_connection_username "$XENAPI_USER"
-        iniset $Q_RR_CONF_FILE XENAPI xenapi_connection_password "$XENAPI_PASSWORD"
-
-        # Under XS/XCP, the ovs agent needs to target the dom0
-        # integration bridge.  This is enabled by using a root wrapper
-        # that executes commands on dom0 via a XenAPI plugin.
-        iniset /$Q_PLUGIN_CONF_FILE AGENT root_helper "$Q_RR_DOM0_COMMAND"
-
-        # Set "physical" mapping
-        iniset /$Q_PLUGIN_CONF_FILE OVS bridge_mappings "physnet1:$FLAT_NETWORK_BRIDGE"
-
-        # XEN_INTEGRATION_BRIDGE is the integration bridge in dom0
-        iniset /$Q_PLUGIN_CONF_FILE OVS integration_bridge $XEN_INTEGRATION_BRIDGE
-
-        # Set up domU's L2 agent:
-
-        # Create a bridge "br-$GUEST_INTERFACE_DEFAULT"
-        sudo ovs-vsctl --no-wait -- --may-exist add-br "br-$GUEST_INTERFACE_DEFAULT"
-        # Add $GUEST_INTERFACE_DEFAULT to that bridge
-        sudo ovs-vsctl add-port "br-$GUEST_INTERFACE_DEFAULT" $GUEST_INTERFACE_DEFAULT
-
-        # Set bridge mappings to "physnet1:br-$GUEST_INTERFACE_DEFAULT"
-        iniset "/$Q_PLUGIN_CONF_FILE.domU" OVS bridge_mappings "physnet1:br-$GUEST_INTERFACE_DEFAULT"
-        # Set integration bridge to domU's
-        iniset "/$Q_PLUGIN_CONF_FILE.domU" OVS integration_bridge $OVS_BRIDGE
-        # Set root wrap
-        iniset "/$Q_PLUGIN_CONF_FILE.domU" AGENT root_helper "$Q_RR_COMMAND"
-    fi
-}
-
 function quantum_plugin_configure_service() {
     if [[ "$ENABLE_TENANT_TUNNELS" = "True" ]]; then
         iniset /$Q_PLUGIN_CONF_FILE OVS tenant_network_type gre
@@ -141,18 +44,9 @@
     _quantum_ovs_base_configure_firewall_driver
 }
 
-function quantum_plugin_setup_interface_driver() {
-    local conf_file=$1
-    iniset $conf_file DEFAULT interface_driver quantum.agent.linux.interface.OVSInterfaceDriver
-}
-
 function has_quantum_plugin_security_group() {
     return 0
 }
 
-function quantum_plugin_check_adv_test_requirements() {
-    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
-}
-
 # Restore xtrace
 $MY_XTRACE
diff --git a/lib/quantum_plugins/openvswitch_agent b/lib/quantum_plugins/openvswitch_agent
new file mode 100644
index 0000000..87f5e97
--- /dev/null
+++ b/lib/quantum_plugins/openvswitch_agent
@@ -0,0 +1,117 @@
+# Quantum Open vSwitch L2 agent
+# -----------------------------
+
+# Save trace setting
+PLUGIN_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+source $TOP_DIR/lib/quantum_plugins/ovs_base
+
+function quantum_plugin_create_nova_conf() {
+    _quantum_ovs_base_configure_nova_vif_driver
+    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
+        iniset $NOVA_CONF DEFAULT xenapi_vif_driver nova.virt.xenapi.vif.XenAPIOpenVswitchDriver
+        iniset $NOVA_CONF DEFAULT xenapi_ovs_integration_bridge $XEN_INTEGRATION_BRIDGE
+        # Disable nova's firewall so that it does not conflict with quantum
+        iniset $NOVA_CONF DEFAULT firewall_driver nova.virt.firewall.NoopFirewallDriver
+    fi
+}
+
+function quantum_plugin_install_agent_packages() {
+    _quantum_ovs_base_install_agent_packages
+}
+
+function quantum_plugin_configure_debug_command() {
+    _quantum_ovs_base_configure_debug_command
+}
+
+function quantum_plugin_configure_dhcp_agent() {
+    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager quantum.agent.dhcp_agent.DhcpAgentWithStateReport
+}
+
+function quantum_plugin_configure_l3_agent() {
+    _quantum_ovs_base_configure_l3_agent
+    iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager quantum.agent.l3_agent.L3NATAgentWithStateReport
+}
+
+function quantum_plugin_configure_plugin_agent() {
+    # Setup integration bridge
+    _quantum_ovs_base_setup_bridge $OVS_BRIDGE
+    _quantum_ovs_base_configure_firewall_driver
+
+    # Setup agent for tunneling
+    if [[ "$OVS_ENABLE_TUNNELING" = "True" ]]; then
+        # Verify tunnels are supported
+        # REVISIT - also check kernel module support for GRE and patch ports
+        OVS_VERSION=`ovs-vsctl --version | head -n 1 | awk '{print $4;}'`
+        if [ $OVS_VERSION \< "1.4" ] && ! is_service_enabled q-svc ; then
+            die $LINENO "You are running OVS version $OVS_VERSION. OVS 1.4+ is required for tunneling between multiple hosts."
+        fi
+        iniset /$Q_PLUGIN_CONF_FILE OVS enable_tunneling True
+        iniset /$Q_PLUGIN_CONF_FILE OVS local_ip $HOST_IP
+    fi
+
+    # Setup physical network bridge mappings.  Override
+    # ``OVS_VLAN_RANGES`` and ``OVS_BRIDGE_MAPPINGS`` in ``localrc`` for more
+    # complex physical network configurations.
+    if [[ "$OVS_BRIDGE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$OVS_PHYSICAL_BRIDGE" != "" ]]; then
+        OVS_BRIDGE_MAPPINGS=$PHYSICAL_NETWORK:$OVS_PHYSICAL_BRIDGE
+
+        # Configure bridge manually with physical interface as port for multi-node
+        sudo ovs-vsctl --no-wait -- --may-exist add-br $OVS_PHYSICAL_BRIDGE
+    fi
+    if [[ "$OVS_BRIDGE_MAPPINGS" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE OVS bridge_mappings $OVS_BRIDGE_MAPPINGS
+    fi
+    AGENT_BINARY="$QUANTUM_DIR/bin/quantum-openvswitch-agent"
+
+    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
+        # Make a copy of our config for domU
+        sudo cp /$Q_PLUGIN_CONF_FILE "/$Q_PLUGIN_CONF_FILE.domu"
+
+        # Deal with Dom0's L2 Agent:
+        Q_RR_DOM0_COMMAND="$QUANTUM_DIR/bin/quantum-rootwrap-xen-dom0 $Q_RR_CONF_FILE"
+
+        # For now, duplicate the xen configuration already found in nova.conf
+        iniset $Q_RR_CONF_FILE XENAPI xenapi_connection_url "$XENAPI_CONNECTION_URL"
+        iniset $Q_RR_CONF_FILE XENAPI xenapi_connection_username "$XENAPI_USER"
+        iniset $Q_RR_CONF_FILE XENAPI xenapi_connection_password "$XENAPI_PASSWORD"
+
+        # Under XS/XCP, the ovs agent needs to target the dom0
+        # integration bridge.  This is enabled by using a root wrapper
+        # that executes commands on dom0 via a XenAPI plugin.
+        iniset /$Q_PLUGIN_CONF_FILE AGENT root_helper "$Q_RR_DOM0_COMMAND"
+
+        # Set "physical" mapping
+        iniset /$Q_PLUGIN_CONF_FILE OVS bridge_mappings "physnet1:$FLAT_NETWORK_BRIDGE"
+
+        # XEN_INTEGRATION_BRIDGE is the integration bridge in dom0
+        iniset /$Q_PLUGIN_CONF_FILE OVS integration_bridge $XEN_INTEGRATION_BRIDGE
+
+        # Set up domU's L2 agent:
+
+        # Create a bridge "br-$GUEST_INTERFACE_DEFAULT"
+        sudo ovs-vsctl --no-wait -- --may-exist add-br "br-$GUEST_INTERFACE_DEFAULT"
+        # Add $GUEST_INTERFACE_DEFAULT to that bridge
+        sudo ovs-vsctl add-port "br-$GUEST_INTERFACE_DEFAULT" $GUEST_INTERFACE_DEFAULT
+
+        # Set bridge mappings to "physnet1:br-$GUEST_INTERFACE_DEFAULT"
+        iniset "/$Q_PLUGIN_CONF_FILE.domU" OVS bridge_mappings "physnet1:br-$GUEST_INTERFACE_DEFAULT"
+        # Set integration bridge to domU's
+        iniset "/$Q_PLUGIN_CONF_FILE.domU" OVS integration_bridge $OVS_BRIDGE
+        # Set root wrap
+        iniset "/$Q_PLUGIN_CONF_FILE.domU" AGENT root_helper "$Q_RR_COMMAND"
+    fi
+}
+
+function quantum_plugin_setup_interface_driver() {
+    local conf_file=$1
+    iniset $conf_file DEFAULT interface_driver quantum.agent.linux.interface.OVSInterfaceDriver
+}
+
+function quantum_plugin_check_adv_test_requirements() {
+    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
+}
+
+# Restore xtrace
+$PLUGIN_XTRACE
diff --git a/rejoin-stack.sh b/rejoin-stack.sh
index c452694..65ba721 100755
--- a/rejoin-stack.sh
+++ b/rejoin-stack.sh
@@ -5,6 +5,10 @@
 
 TOP_DIR=`dirname $0`
 
+# Import common functions in case the localrc (loaded via stackrc)
+# uses them.
+source $TOP_DIR/functions
+
 source $TOP_DIR/stackrc
 
 # if screenrc exists, run screen