Skip to content

Commit ea93a5c

Browse files
authored
Merge pull request #3260 from vkarak/enhancement/change-db-file-mode
[enhancement] Allow setting the file mode of the SQLite database
2 parents 0bd2163 + 2b97cb7 commit ea93a5c

File tree

5 files changed

+61
-7
lines changed

5 files changed

+61
-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: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import os
88
import re
99
import sqlite3
10+
import sys
1011
from filelock import FileLock
1112

1213
import reframe.utility.jsonext as jsonext
@@ -52,6 +53,13 @@ def __init__(self):
5253
self.__db_file = os.path.join(
5354
osext.expandvars(runtime().get_option('storage/0/sqlite_db_file'))
5455
)
56+
mode = runtime().get_option(
57+
'storage/0/sqlite_db_file_mode'
58+
)
59+
if not isinstance(mode, int):
60+
self.__db_file_mode = int(mode, base=8)
61+
else:
62+
self.__db_file_mode = mode
5563

5664
def _db_file(self):
5765
prefix = os.path.dirname(self.__db_file)
@@ -78,6 +86,18 @@ def _db_connect(self, *args, **kwargs):
7886
with getprofiler().time_region('sqlite connect'):
7987
return sqlite3.connect(*args, **kwargs)
8088

89+
def _db_lock(self):
90+
prefix = os.path.dirname(self.__db_file)
91+
if sys.version_info >= (3, 7):
92+
kwargs = {'mode': self.__db_file_mode}
93+
else:
94+
# Python 3.6 forces us to use an older filelock version that does
95+
# not support file modes. File modes where introduced in
96+
# filelock 3.10
97+
kwargs = {}
98+
99+
return FileLock(os.path.join(prefix, '.db.lock'), **kwargs)
100+
81101
def _db_create(self):
82102
clsname = type(self).__name__
83103
getlogger().debug(
@@ -104,6 +124,8 @@ def _db_create(self):
104124
'on testcases(job_completion_time_unix)')
105125
conn.execute('CREATE TABLE IF NOT EXISTS metadata('
106126
'schema_version TEXT)')
127+
# Update DB file mode
128+
os.chmod(self.__db_file, self.__db_file_mode)
107129

108130
def _db_schema_check(self):
109131
with self._db_connect(self.__db_file) as conn:
@@ -164,9 +186,8 @@ def _db_store_report(self, conn, report, report_file_path):
164186
return session_uuid
165187

166188
def store(self, report, report_file=None):
167-
prefix = os.path.dirname(self.__db_file)
168189
with self._db_connect(self._db_file()) as conn:
169-
with FileLock(os.path.join(prefix, '.db.lock')):
190+
with self._db_lock():
170191
return self._db_store_report(conn, report, report_file)
171192

172193
@time_function
@@ -298,8 +319,7 @@ def fetch_session_json(self, uuid):
298319
return jsonext.loads(results[0][0]) if results else {}
299320

300321
def _do_remove(self, uuid):
301-
prefix = os.path.dirname(self.__db_file)
302-
with FileLock(os.path.join(prefix, '.db.lock')):
322+
with self._db_lock():
303323
with self._db_connect(self._db_file()) as conn:
304324
# Enable foreign keys for delete action to have cascade effect
305325
conn.execute('PRAGMA foreign_keys = ON')
@@ -316,8 +336,7 @@ def _do_remove(self, uuid):
316336

317337
def _do_remove2(self, uuid):
318338
'''Remove a session using the RETURNING keyword'''
319-
prefix = os.path.dirname(self.__db_file)
320-
with FileLock(os.path.join(prefix, '.db.lock')):
339+
with self._db_lock():
321340
with self._db_connect(self._db_file()) as conn:
322341
# Enable foreign keys for delete action to have cascade effect
323342
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)