]>
Commit | Line | Data |
---|---|---|
b0b8729a SS |
1 | commit 63e16feedea3639ef1f21fecbff9ed2ae256728b |
2 | Author: Michael Tremer <michael.tremer@ipfire.org> | |
3 | Date: Sat Apr 25 13:18:07 2015 +0200 | |
4 | ||
5 | Perform lazy initialization of the database | |
6 | ||
7 | The database will only be initialized when it is actually | |
8 | needed. That makes starting up ddns a bit faster and allows | |
9 | us to execute it as non-root for simple commands like | |
10 | "list-providers". | |
11 | ||
12 | If the database path is not writable at all, the database | |
13 | feature is disable and an error message is logged. This | |
14 | will hopefully help us to perform the DNS update even when | |
15 | there is a local misconfiguration. | |
16 | ||
17 | diff --git a/src/ddns/database.py b/src/ddns/database.py | |
18 | index 5d4ffc9..42c3433 100644 | |
19 | --- a/src/ddns/database.py | |
20 | +++ b/src/ddns/database.py | |
21 | @@ -20,7 +20,7 @@ | |
22 | ############################################################################### | |
23 | ||
24 | import datetime | |
25 | -import os.path | |
26 | +import os | |
27 | import sqlite3 | |
28 | ||
29 | # Initialize the logger. | |
30 | @@ -31,9 +31,11 @@ logger.propagate = 1 | |
31 | class DDNSDatabase(object): | |
32 | def __init__(self, core, path): | |
33 | self.core = core | |
34 | + self.path = path | |
35 | ||
36 | - # Open the database file | |
37 | - self._db = self._open_database(path) | |
38 | + # We won't open the connection to the database directly | |
39 | + # so that we do not do it unnecessarily. | |
40 | + self._db = None | |
41 | ||
42 | def __del__(self): | |
43 | self._close_database() | |
44 | @@ -46,7 +48,7 @@ class DDNSDatabase(object): | |
45 | conn = sqlite3.connect(path, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) | |
46 | conn.isolation_level = None | |
47 | ||
48 | - if not exists: | |
49 | + if not exists and self.is_writable(): | |
50 | logger.debug("Initialising database layout") | |
51 | c = conn.cursor() | |
52 | c.executescript(""" | |
53 | @@ -68,12 +70,25 @@ class DDNSDatabase(object): | |
54 | ||
55 | return conn | |
56 | ||
57 | + def is_writable(self): | |
58 | + # Check if the database file exists and is writable. | |
59 | + ret = os.access(self.path, os.W_OK) | |
60 | + if ret: | |
61 | + return True | |
62 | + | |
63 | + # If not, we check if we are able to write to the directory. | |
64 | + # In that case the database file will be created in _open_database(). | |
65 | + return os.access(os.path.dirname(self.path), os.W_OK) | |
66 | + | |
67 | def _close_database(self): | |
68 | if self._db: | |
69 | self._db_close() | |
70 | self._db = None | |
71 | ||
72 | def _execute(self, query, *parameters): | |
73 | + if self._db is None: | |
74 | + self._db = self._open_database(self.path) | |
75 | + | |
76 | c = self._db.cursor() | |
77 | try: | |
78 | c.execute(query, parameters) | |
79 | @@ -81,6 +96,10 @@ class DDNSDatabase(object): | |
80 | c.close() | |
81 | ||
82 | def add_update(self, hostname, status, message=None): | |
83 | + if not self.is_writable(): | |
84 | + logger.warning("Could not log any updates because the database is not writable") | |
85 | + return | |
86 | + | |
87 | self._execute("INSERT INTO updates(hostname, status, message, timestamp) \ | |
88 | VALUES(?, ?, ?, ?)", hostname, status, message, datetime.datetime.utcnow()) | |
89 |