summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-09-20 09:03:07 -0400
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-09-21 15:32:58 -0400
commit02b9432e736f3951078f3ad232baa445ca5d30b1 (patch)
treebca487a1fbecd877c77e65963e0587af279992ff
parent89badf50b797d7b76e37e71c27cba47264c560bf (diff)
downloadpython-systemd-02b9432e736f3951078f3ad232baa445ca5d30b1.tar.gz
reader: add SD_JOURNAL_OS_ROOT and rework flag passing
Let's pass any flags through to the journal functions without checking validity. Those functions do their own checking, so there's no need to second-guess. The semantics for _Reader(flags=0) are a bit changed: before, this would be transformed into sd_journal_open(SD_J_LOCAL_ONLY). Now, this results in sd_journal_open(0). Previous behaviour should be achieved by not specifying the flags at all. This change is necessary, because previously it was not possible to pass flags=0 to sd_journal_open(0), i.e. it was not possible to "merge" journals through the Python interface. Similarly, Reader(flags=0) now means to open all journals, and Reader(flags=None) is the same as Reader(flags=LOCAL_ONLY).
-rw-r--r--docs/journal.rst1
-rw-r--r--systemd/_reader.c29
-rw-r--r--systemd/journal.py10
-rw-r--r--systemd/test/test_journal.py35
4 files changed, 51 insertions, 24 deletions
diff --git a/docs/journal.rst b/docs/journal.rst
index 8e4b5b6..49c07b1 100644
--- a/docs/journal.rst
+++ b/docs/journal.rst
@@ -89,6 +89,7 @@ Journal access types
.. autoattribute:: systemd.journal.RUNTIME_ONLY
.. autoattribute:: systemd.journal.SYSTEM
.. autoattribute:: systemd.journal.CURRENT_USER
+.. autoattribute:: systemd.journal.OS_ROOT
Journal event types
~~~~~~~~~~~~~~~~~~~
diff --git a/systemd/_reader.c b/systemd/_reader.c
index 020bfbd..0f6fd3f 100644
--- a/systemd/_reader.c
+++ b/systemd/_reader.c
@@ -34,8 +34,8 @@
#if defined(LIBSYSTEMD_VERSION) || LIBSYSTEMD_JOURNAL_VERSION > 204
# define HAVE_JOURNAL_OPEN_FILES
#else
-# define SD_JOURNAL_SYSTEM 4
-# define SD_JOURNAL_CURRENT_USER 8
+# define SD_JOURNAL_SYSTEM (1 << 2)
+# define SD_JOURNAL_CURRENT_USER (1 << 3)
#endif
#if LIBSYSTEMD_VERSION >= 229
@@ -46,6 +46,8 @@
#if LIBSYSTEMD_VERSION >= 230
# define HAVE_JOURNAL_OPEN_DIRECTORY_FD
+#else
+# define SD_JOURNAL_OS_ROOT (1 << 4)
#endif
typedef struct {
@@ -225,7 +227,9 @@ PyDoc_STRVAR(Reader__doc__,
"Argument `flags` sets open flags of the journal, which can be one of, or an ORed\n"
"combination of constants: LOCAL_ONLY (default) opens journal on local machine only;\n"
"RUNTIME_ONLY opens only volatile journal files; and SYSTEM opens journal files of\n"
- "system services and the kernel, and CURRENT_USER opens file of the current user.\n"
+ "system services and the kernel, CURRENT_USER opens files of the current user; and\n"
+ "OS_ROOT is used to open the journal from directories relative to the specified\n"
+ "directory path or file descriptor.\n"
"\n"
"Instead of opening the system journal, argument `path` may specify a directory\n"
"which contains the journal. It maybe be either a file system path (a string), or\n"
@@ -235,8 +239,9 @@ PyDoc_STRVAR(Reader__doc__,
"_Reader implements the context manager protocol: the journal will be closed when\n"
"exiting the block.");
static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) {
- int flags = 0, r;
+ unsigned flags = SD_JOURNAL_LOCAL_ONLY;
PyObject *_path = NULL, *_files = NULL;
+ int r;
static const char* const kwlist[] = {"flags", "path", "files", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "|iO&O&:__init__", (char**) kwlist,
@@ -245,9 +250,9 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) {
null_converter, &_files))
return -1;
- if (!!flags + !!_path + !!_files > 1) {
+ if (!!_path + !!_files > 1) {
PyErr_SetString(PyExc_ValueError,
- "cannot use more than one of flags, path, and files");
+ "path and files cannot be specified simultaneously");
return -1;
}
@@ -260,7 +265,7 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) {
#ifdef HAVE_JOURNAL_OPEN_DIRECTORY_FD
Py_BEGIN_ALLOW_THREADS
- r = sd_journal_open_directory_fd(&self->j, (int) fd, 0);
+ r = sd_journal_open_directory_fd(&self->j, (int) fd, flags);
Py_END_ALLOW_THREADS
#else
r = -ENOSYS;
@@ -274,7 +279,7 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) {
return -1;
Py_BEGIN_ALLOW_THREADS
- r = sd_journal_open_directory(&self->j, path, 0);
+ r = sd_journal_open_directory(&self->j, path, flags);
Py_END_ALLOW_THREADS
}
} else if (_files) {
@@ -289,7 +294,7 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) {
return -1;
Py_BEGIN_ALLOW_THREADS
- r = sd_journal_open_files(&self->j, (const char**) files, 0);
+ r = sd_journal_open_files(&self->j, (const char**) files, flags);
Py_END_ALLOW_THREADS
} else {
_cleanup_free_ int *fds = NULL;
@@ -299,16 +304,13 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) {
return -1;
Py_BEGIN_ALLOW_THREADS
- r = sd_journal_open_files_fd(&self->j, fds, n_fds, 0);
+ r = sd_journal_open_files_fd(&self->j, fds, n_fds, flags);
Py_END_ALLOW_THREADS
}
#else
r = -ENOSYS;
#endif
} else {
- if (!flags)
- flags = SD_JOURNAL_LOCAL_ONLY;
-
Py_BEGIN_ALLOW_THREADS
r = sd_journal_open(&self->j, flags);
Py_END_ALLOW_THREADS
@@ -1332,6 +1334,7 @@ init_reader(void)
PyModule_AddIntConstant(m, "SYSTEM", SD_JOURNAL_SYSTEM) ||
PyModule_AddIntConstant(m, "SYSTEM_ONLY", SD_JOURNAL_SYSTEM_ONLY) ||
PyModule_AddIntConstant(m, "CURRENT_USER", SD_JOURNAL_CURRENT_USER) ||
+ PyModule_AddIntConstant(m, "OS_ROOT", SD_JOURNAL_OS_ROOT) ||
PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION)) {
#if PY_MAJOR_VERSION >= 3
Py_DECREF(m);
diff --git a/systemd/journal.py b/systemd/journal.py
index 4440dec..b91337d 100644
--- a/systemd/journal.py
+++ b/systemd/journal.py
@@ -34,6 +34,7 @@ from ._journal import __version__, sendv, stream_fd
from ._reader import (_Reader, NOP, APPEND, INVALIDATE,
LOCAL_ONLY, RUNTIME_ONLY,
SYSTEM, SYSTEM_ONLY, CURRENT_USER,
+ OS_ROOT,
_get_catalog)
from . import id128 as _id128
@@ -131,7 +132,7 @@ class Reader(_Reader):
journal.
"""
- def __init__(self, flags=0, path=None, files=None, converters=None):
+ def __init__(self, flags=None, path=None, files=None, converters=None):
"""Create a new Reader.
Argument `flags` defines the open flags of the journal, which can be one
@@ -155,6 +156,13 @@ class Reader(_Reader):
Reader implements the context manager protocol: the journal will be
closed when exiting the block.
"""
+ if flags is None:
+ if path is None and files is None:
+ # This mimics journalctl behaviour of default to local journal only
+ flags = LOCAL_ONLY
+ else:
+ flags = 0
+
super(Reader, self).__init__(flags, path, files)
if _sys.version_info >= (3,3):
self.converters = _ChainMap()
diff --git a/systemd/test/test_journal.py b/systemd/test/test_journal.py
index 4b23a70..10a57e9 100644
--- a/systemd/test/test_journal.py
+++ b/systemd/test/test_journal.py
@@ -43,15 +43,25 @@ def test_reader_init_flags():
j2 = journal.Reader(journal.LOCAL_ONLY)
j3 = journal.Reader(journal.RUNTIME_ONLY)
j4 = journal.Reader(journal.SYSTEM_ONLY)
- j5 = journal.Reader(journal.LOCAL_ONLY|
- journal.RUNTIME_ONLY|
- journal.SYSTEM_ONLY)
+ j5 = journal.Reader(journal.LOCAL_ONLY | journal.RUNTIME_ONLY | journal.SYSTEM_ONLY)
j6 = journal.Reader(0)
-def test_reader_init_path(tmpdir):
- j = journal.Reader(path=tmpdir.strpath)
+def test_reader_os_root(tmpdir):
with pytest.raises(ValueError):
- journal.Reader(journal.LOCAL_ONLY, path=tmpdir.strpath)
+ journal.Reader(journal.OS_ROOT)
+ j1 = journal.Reader(path=tmpdir.strpath,
+ flags=journal.OS_ROOT)
+ j2 = journal.Reader(path=tmpdir.strpath,
+ flags=journal.OS_ROOT | journal.CURRENT_USER)
+ j3 = journal.Reader(path=tmpdir.strpath,
+ flags=journal.OS_ROOT | journal.SYSTEM_ONLY)
+
+def test_reader_init_path(tmpdir):
+ j1 = journal.Reader(path=tmpdir.strpath)
+ journal.Reader(0, path=tmpdir.strpath)
+
+ j2 = journal.Reader(path=tmpdir.strpath)
+ journal.Reader(path=tmpdir.strpath)
def test_reader_init_path_invalid_fd():
with pytest.raises(OSError):
@@ -63,10 +73,15 @@ def test_reader_init_path_nondirectory_fd():
def test_reader_init_path_fd(tmpdir):
fd = os.open(tmpdir.strpath, os.O_RDONLY)
- j = journal.Reader(path=fd)
- with pytest.raises(ValueError):
- journal.Reader(journal.LOCAL_ONLY, path=fd)
- assert list(j) == []
+
+ j1 = journal.Reader(path=fd)
+ assert list(j1) == []
+
+ j2 = journal.Reader(journal.SYSTEM, path=fd)
+ assert list(j2) == []
+
+ j3 = journal.Reader(journal.CURRENT_USER, path=fd)
+ assert list(j3) == []
def test_reader_as_cm(tmpdir):
j = journal.Reader(path=tmpdir.strpath)