Skip to content

Commit 5b75350

Browse files
committed
Allow setting the file mode of the SQLite database
1 parent 0bd2163 commit 5b75350

File tree

5 files changed

+49
-7
lines changed

5 files changed

+49
-7
lines changed

docs/config_reference.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,6 +1651,16 @@ Result storage configuration
16511651

16521652
The SQLite database file to use.
16531653

1654+
.. py:attribute:: storage.sqlite_db_file_mode
1655+
1656+
:required: No
1657+
:default: ``"644"``
1658+
1659+
The permissions of the SQLite database file in octal form.
1660+
1661+
The mode will only taken into account upon creation of the DB file.
1662+
Permissions of an existing DB file have to be changed manually.
1663+
16541664

16551665
General Configuration
16561666
=====================

docs/manpage.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,6 +2038,21 @@ Whenever an environment variable is associated with a configuration option, its
20382038
.. versionadded:: 4.7
20392039

20402040

2041+
.. envvar:: RFM_SQLITE_DB_FILE_MODE
2042+
2043+
The permissions of the SQLite database file in octal form.
2044+
2045+
.. table::
2046+
:align: left
2047+
2048+
================================== ==================
2049+
Associated command line option N/A
2050+
Associated configuration parameter :attr:`~config.storage.sqlite_db_file_mode`
2051+
================================== ==================
2052+
2053+
.. versionadded:: 4.7
2054+
2055+
20412056
.. envvar:: RFM_SYSLOG_ADDRESS
20422057

20432058
The address of the Syslog server to send performance logs.

reframe/frontend/cli.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#
44
# SPDX-License-Identifier: BSD-3-Clause
55

6+
import functools
67
import inspect
78
import itertools
89
import json
@@ -777,6 +778,13 @@ def main():
777778
configvar='storage/sqlite_db_file',
778779
help='DB file where the results database resides (SQLite backend)'
779780
)
781+
argparser.add_argument(
782+
dest='sqlite_db_file_mode',
783+
envvar='RFM_SQLITE_DB_FILE_MODE',
784+
configvar='storage/sqlite_db_file_mode',
785+
help='DB file permissions (SQLite backend)',
786+
type=functools.partial(int, base=8)
787+
)
780788
argparser.add_argument(
781789
dest='syslog_address',
782790
envvar='RFM_SYSLOG_ADDRESS',

reframe/frontend/reporting/storage.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ def __init__(self):
5252
self.__db_file = os.path.join(
5353
osext.expandvars(runtime().get_option('storage/0/sqlite_db_file'))
5454
)
55+
self.__db_file_mode = runtime().get_option(
56+
'storage/0/sqlite_db_file_mode'
57+
)
5558

5659
def _db_file(self):
5760
prefix = os.path.dirname(self.__db_file)
@@ -78,6 +81,11 @@ def _db_connect(self, *args, **kwargs):
7881
with getprofiler().time_region('sqlite connect'):
7982
return sqlite3.connect(*args, **kwargs)
8083

84+
def _db_lock(self):
85+
prefix = os.path.dirname(self.__db_file)
86+
return FileLock(os.path.join(prefix, '.db.lock'),
87+
mode=self.__db_file_mode)
88+
8189
def _db_create(self):
8290
clsname = type(self).__name__
8391
getlogger().debug(
@@ -104,6 +112,8 @@ def _db_create(self):
104112
'on testcases(job_completion_time_unix)')
105113
conn.execute('CREATE TABLE IF NOT EXISTS metadata('
106114
'schema_version TEXT)')
115+
# Update DB file mode
116+
os.chmod(self.__db_file, self.__db_file_mode)
107117

108118
def _db_schema_check(self):
109119
with self._db_connect(self.__db_file) as conn:
@@ -164,9 +174,8 @@ def _db_store_report(self, conn, report, report_file_path):
164174
return session_uuid
165175

166176
def store(self, report, report_file=None):
167-
prefix = os.path.dirname(self.__db_file)
168177
with self._db_connect(self._db_file()) as conn:
169-
with FileLock(os.path.join(prefix, '.db.lock')):
178+
with self._db_lock():
170179
return self._db_store_report(conn, report, report_file)
171180

172181
@time_function
@@ -298,8 +307,7 @@ def fetch_session_json(self, uuid):
298307
return jsonext.loads(results[0][0]) if results else {}
299308

300309
def _do_remove(self, uuid):
301-
prefix = os.path.dirname(self.__db_file)
302-
with FileLock(os.path.join(prefix, '.db.lock')):
310+
with self._db_lock():
303311
with self._db_connect(self._db_file()) as conn:
304312
# Enable foreign keys for delete action to have cascade effect
305313
conn.execute('PRAGMA foreign_keys = ON')
@@ -316,8 +324,7 @@ def _do_remove(self, uuid):
316324

317325
def _do_remove2(self, uuid):
318326
'''Remove a session using the RETURNING keyword'''
319-
prefix = os.path.dirname(self.__db_file)
320-
with FileLock(os.path.join(prefix, '.db.lock')):
327+
with self._db_lock():
321328
with self._db_connect(self._db_file()) as conn:
322329
# Enable foreign keys for delete action to have cascade effect
323330
conn.execute('PRAGMA foreign_keys = ON')

reframe/schemas/config.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,8 @@
544544
"properties": {
545545
"backend": {"type": "string"},
546546
"sqlite_conn_timeout": {"type": "number"},
547-
"sqlite_db_file": {"type": "string"}
547+
"sqlite_db_file": {"type": "string"},
548+
"sqlite_db_file_mode": {"type": "string"}
548549
}
549550
}
550551
}
@@ -627,6 +628,7 @@
627628
"storage/backend": "sqlite",
628629
"storage/sqlite_conn_timeout": 60,
629630
"storage/sqlite_db_file": "${HOME}/.reframe/reports/results.db",
631+
"storage/sqlite_db_file_mode": "644",
630632
"systems/descr": "",
631633
"systems/max_local_jobs": 8,
632634
"systems/modules_system": "nomod",

0 commit comments

Comments
 (0)