blueprint database-common
This fixes bug 995438. If there is an database failure, for example, the mysql service is down, then the agent or the service will attempt to reconnect to the database every 'reconnect_interval'. Change-Id: Iaee24b08e07a4f4dde5e27f31d3a5f81f5101466
This commit is contained in:
parent
a90d63cbb0
commit
6bcc236ea3
|
@ -3,17 +3,14 @@ vlan_start=1000
|
|||
vlan_end=3000
|
||||
|
||||
[DATABASE]
|
||||
# Use the following when running the tests for the in-memory DB
|
||||
connection = sqlite
|
||||
# Uncomment the following for using the MySQL DB when actually running the plugin,
|
||||
# also remove the earlier sqlite connection configuration
|
||||
#connection = mysql
|
||||
name = quantum_linux_bridge
|
||||
user = <mysql_user_name_here>
|
||||
pass = <mysql_password_here>
|
||||
host = <hostname_or_IP_address_of_Quantum_server>
|
||||
# If you use a non-default port for the DB, change the following
|
||||
port = 3306
|
||||
# This line MUST be changed to actually run the plugin.
|
||||
# Example:
|
||||
# sql_connection = mysql://root:nova@127.0.0.1:3306/quantum_linux_bridge
|
||||
# Replace 127.0.0.1 above with the IP address of the database used by the
|
||||
# main quantum server. (Leave it as is if the database runs on this host.)
|
||||
sql_connection = sqlite://
|
||||
# Database reconnection interval in seconds - in event connectivity is lost
|
||||
reconnect_interval = 2
|
||||
|
||||
[LINUX_BRIDGE]
|
||||
# This is the interface connected to the switch on your Quantum network
|
||||
|
@ -22,8 +19,6 @@ physical_interface = eth1
|
|||
[AGENT]
|
||||
# Agent's polling interval in seconds
|
||||
polling_interval = 2
|
||||
# Agent's database reconnection interval in seconds - in event connectivity is lost
|
||||
reconnect_interval = 2
|
||||
# Change to "sudo quantum-rootwrap" to limit commands that can be run
|
||||
# as root.
|
||||
root_helper = sudo
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
[DATABASE]
|
||||
# This line MUST be changed to actually run the plugin.
|
||||
# Example: sql_connection = mysql://root:nova@127.0.0.1:3306/ovs_quantum
|
||||
# Example:
|
||||
# sql_connection = mysql://root:nova@127.0.0.1:3306/ovs_quantum
|
||||
# Replace 127.0.0.1 above with the IP address of the database used by the
|
||||
# main quantum server. (Leave it as is if the database runs on this host.)
|
||||
sql_connection = sqlite://
|
||||
# Database reconnection interval in seconds - in event connectivity is lost
|
||||
reconnect_interval = 2
|
||||
|
||||
[OVS]
|
||||
# This enables the new OVSQuantumTunnelAgent which enables tunneling
|
||||
|
@ -34,8 +37,6 @@ integration-bridge = br-int
|
|||
[AGENT]
|
||||
# Agent's polling interval in seconds
|
||||
polling_interval = 2
|
||||
# Agent's database reconnection interval in seconds - in event connectivity is lost
|
||||
reconnect_interval = 2
|
||||
# Change to "sudo quantum-rootwrap" to limit commands that can be run
|
||||
# as root.
|
||||
root_helper = sudo
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
# @author: Dan Wendlandt, Nicira Networks, Inc.
|
||||
|
||||
import logging
|
||||
import time
|
||||
|
||||
import sqlalchemy as sql
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.exc import DisconnectionError
|
||||
|
@ -75,7 +77,9 @@ def configure_db(options):
|
|||
engine_args['listeners'] = [MySQLPingListener()]
|
||||
|
||||
_ENGINE = create_engine(options['sql_connection'], **engine_args)
|
||||
register_models()
|
||||
if not register_models():
|
||||
if 'reconnect_interval' in options:
|
||||
retry_registration(options['reconnect_interval'])
|
||||
|
||||
|
||||
def clear_db():
|
||||
|
@ -96,11 +100,25 @@ def get_session(autocommit=True, expire_on_commit=False):
|
|||
return _MAKER()
|
||||
|
||||
|
||||
def retry_registration(reconnect_interval):
|
||||
while True:
|
||||
LOG.info("Unable to connect to database. Retrying in %s seconds" %
|
||||
reconnect_interval)
|
||||
time.sleep(reconnect_interval)
|
||||
if register_models():
|
||||
break
|
||||
|
||||
|
||||
def register_models():
|
||||
"""Register Models and create properties"""
|
||||
global _ENGINE
|
||||
assert _ENGINE
|
||||
BASE.metadata.create_all(_ENGINE)
|
||||
try:
|
||||
BASE.metadata.create_all(_ENGINE)
|
||||
except sql.exc.OperationalError as e:
|
||||
LOG.info("Database registration exception: %s" % e)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def unregister_models():
|
||||
|
|
|
@ -473,26 +473,17 @@ def main():
|
|||
else:
|
||||
polling_interval = DEFAULT_POLLING_INTERVAL
|
||||
LOG.info("Polling interval not defined. Using default.")
|
||||
if config.has_option("AGENT", "reconnect_interval"):
|
||||
reconnect_interval = config.getint("AGENT", "reconnect_interval")
|
||||
if config.has_option("DATABASE", "reconnect_interval"):
|
||||
reconnect_interval = config.getint("DATABASE",
|
||||
"reconnect_interval")
|
||||
else:
|
||||
reconnect_interval = DEFAULT_RECONNECT_INTERVAL
|
||||
LOG.info("Reconnect interval not defined. Using default.")
|
||||
root_helper = config.get("AGENT", "root_helper")
|
||||
'Establish database connection and load models'
|
||||
connection = config.get("DATABASE", "connection")
|
||||
if connection == 'sqlite':
|
||||
LOG.info("Connecting to sqlite DB")
|
||||
db_connection_url = "sqlite:///:memory:"
|
||||
else:
|
||||
db_name = config.get("DATABASE", "name")
|
||||
db_user = config.get("DATABASE", "user")
|
||||
db_pass = config.get("DATABASE", "pass")
|
||||
db_host = config.get("DATABASE", "host")
|
||||
db_port = int(config.get("DATABASE", "port"))
|
||||
LOG.info("Connecting to database %s on %s" % (db_name, db_host))
|
||||
db_connection_url = ("%s://%s:%s@%s:%d/%s" %
|
||||
(connection, db_user, db_pass, db_host, db_port, db_name))
|
||||
db_connection_url = config.get("DATABASE", "sql_connection")
|
||||
LOG.info("Connecting to %s" % (db_connection_url))
|
||||
|
||||
except Exception as e:
|
||||
LOG.error("Unable to parse config file \"%s\": \nException %s" %
|
||||
(config_file, str(e)))
|
||||
|
|
|
@ -32,16 +32,8 @@ LOG = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def initialize():
|
||||
'Establish database connection and load models'
|
||||
if conf.DB_CONNECTION == 'sqlite':
|
||||
options = {"sql_connection": "sqlite://"}
|
||||
else:
|
||||
options = {"sql_connection": "mysql://%s:%s@%s:%s/%s" % (conf.DB_USER,
|
||||
conf.DB_PASS,
|
||||
conf.DB_HOST,
|
||||
conf.DB_PORT,
|
||||
conf.DB_NAME)}
|
||||
|
||||
options = {"sql_connection": "%s" % conf.DB_SQL_CONNECTION}
|
||||
options.update({"reconnect_interval": conf.DB_RECONNECT_INTERVAL})
|
||||
db.configure_db(options)
|
||||
create_vlanids()
|
||||
|
||||
|
|
|
@ -39,10 +39,8 @@ VLAN_END = SECTION_CONF['vlan_end']
|
|||
|
||||
|
||||
SECTION_CONF = CONF_PARSER_OBJ['DATABASE']
|
||||
DB_CONNECTION = SECTION_CONF['connection']
|
||||
if DB_CONNECTION != 'sqlite':
|
||||
DB_NAME = SECTION_CONF['name']
|
||||
DB_USER = SECTION_CONF['user']
|
||||
DB_PASS = SECTION_CONF['pass']
|
||||
DB_HOST = SECTION_CONF['host']
|
||||
DB_PORT = SECTION_CONF['port']
|
||||
DB_SQL_CONNECTION = SECTION_CONF['sql_connection']
|
||||
if 'reconnect_interval' in SECTION_CONF:
|
||||
DB_RECONNECT_INTERVAL = int(SECTION_CONF['reconnect_interval'])
|
||||
else:
|
||||
DB_RECONNECT_INTERVAL = 2
|
||||
|
|
|
@ -394,6 +394,8 @@ class LinuxBridgeAgentTest(unittest.TestCase):
|
|||
self.physical_interface = config.get("LINUX_BRIDGE",
|
||||
"physical_interface")
|
||||
self.polling_interval = config.get("AGENT", "polling_interval")
|
||||
self.reconnect_interval = config.get("DATABASE",
|
||||
"reconnect_interval")
|
||||
self.root_helper = config.get("AGENT", "root_helper")
|
||||
except Exception, e:
|
||||
LOG.error("Unable to parse config file \"%s\": \nException%s"
|
||||
|
@ -406,6 +408,7 @@ class LinuxBridgeAgentTest(unittest.TestCase):
|
|||
self.br_name_prefix,
|
||||
self.physical_interface,
|
||||
self.polling_interval,
|
||||
self.reconnect_interval,
|
||||
self.root_helper)
|
||||
|
||||
def run_cmd(self, args):
|
||||
|
|
|
@ -691,8 +691,9 @@ def main():
|
|||
else:
|
||||
polling_interval = DEFAULT_POLLING_INTERVAL
|
||||
LOG.info("Polling interval not defined. Using default.")
|
||||
if config.has_option("AGENT", "reconnect_interval"):
|
||||
reconnect_interval = config.getint("AGENT", "reconnect_interval")
|
||||
if config.has_option("DATABASE", "reconnect_interval"):
|
||||
reconnect_interval = config.getint("DATABASE",
|
||||
"reconnect_interval")
|
||||
else:
|
||||
reconnect_interval = DEFAULT_RECONNECT_INTERVAL
|
||||
LOG.info("Reconnect interval not defined. Using default.")
|
||||
|
|
|
@ -105,6 +105,12 @@ class OVSQuantumPlugin(QuantumPluginBase):
|
|||
LOG.debug("Config: %s" % config)
|
||||
|
||||
options = {"sql_connection": config.get("DATABASE", "sql_connection")}
|
||||
if config.has_option("DATABASE", "reconnect_interval"):
|
||||
reconnect_interval = config.getint("DATABASE",
|
||||
"reconnect_interval")
|
||||
else:
|
||||
reconnect_interval = 2
|
||||
options.update({"reconnect_interval": reconnect_interval})
|
||||
db.configure_db(options)
|
||||
|
||||
self.vmap = VlanMap()
|
||||
|
|
Loading…
Reference in New Issue