The database will only be initialized when it is actually
needed. That makes starting up ddns a bit faster and allows
us to execute it as non-root for simple commands like
"list-providers".
If the database path is not writable at all, the database
feature is disable and an error message is logged. This
will hopefully help us to perform the DNS update even when
there is a local misconfiguration.
###############################################################################
import datetime
###############################################################################
import datetime
import sqlite3
# Initialize the logger.
import sqlite3
# Initialize the logger.
class DDNSDatabase(object):
def __init__(self, core, path):
self.core = core
class DDNSDatabase(object):
def __init__(self, core, path):
self.core = core
- # Open the database file
- self._db = self._open_database(path)
+ # We won't open the connection to the database directly
+ # so that we do not do it unnecessarily.
+ self._db = None
def __del__(self):
self._close_database()
def __del__(self):
self._close_database()
conn = sqlite3.connect(path, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
conn.isolation_level = None
conn = sqlite3.connect(path, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
conn.isolation_level = None
+ if not exists and self.is_writable():
logger.debug("Initialising database layout")
c = conn.cursor()
c.executescript("""
logger.debug("Initialising database layout")
c = conn.cursor()
c.executescript("""
+ def is_writable(self):
+ # Check if the database file exists and is writable.
+ ret = os.access(self.path, os.W_OK)
+ if ret:
+ return True
+
+ # If not, we check if we are able to write to the directory.
+ # In that case the database file will be created in _open_database().
+ return os.access(os.path.dirname(self.path), os.W_OK)
+
def _close_database(self):
if self._db:
self._db_close()
self._db = None
def _execute(self, query, *parameters):
def _close_database(self):
if self._db:
self._db_close()
self._db = None
def _execute(self, query, *parameters):
+ if self._db is None:
+ self._db = self._open_database(self.path)
+
c = self._db.cursor()
try:
c.execute(query, parameters)
c = self._db.cursor()
try:
c.execute(query, parameters)
c.close()
def add_update(self, hostname, status, message=None):
c.close()
def add_update(self, hostname, status, message=None):
+ if not self.is_writable():
+ logger.warning("Could not log any updates because the database is not writable")
+ return
+
self._execute("INSERT INTO updates(hostname, status, message, timestamp) \
VALUES(?, ?, ?, ?)", hostname, status, message, datetime.datetime.utcnow())
self._execute("INSERT INTO updates(hostname, status, message, timestamp) \
VALUES(?, ?, ?, ?)", hostname, status, message, datetime.datetime.utcnow())