Hello community, here is the log from the commit of package python-systemd for openSUSE:Factory checked in at 2017-07-04 11:56:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-systemd (Old) and /work/SRC/openSUSE:Factory/.python-systemd.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-systemd" Tue Jul 4 11:56:22 2017 rev:5 rq:507119 version:234 Changes: -------- --- /work/SRC/openSUSE:Factory/python-systemd/python-systemd.changes 2017-06-20 09:33:17.408177671 +0200 +++ /work/SRC/openSUSE:Factory/.python-systemd.new/python-systemd.changes 2017-07-04 11:56:24.150187300 +0200 @@ -1,0 +2,39 @@ +Mon Jun 26 09:17:01 UTC 2017 - [email protected] + +- exclude-tests-on-obs.patch: Exclude test which fail because of + a bug in the OBS: https://github.com/openSUSE/obs-build/pull/351 + +- Upgrade to release 234 + * _daemon,_reader: return ENOSYS instead of NotImplemented + * _daemon: allow specifying flowinfo + * Added section for installation on openSUSE & SLE + * Adjust import order, spacing, operators as recommended by pylint + * build-sys: add sign and upload targets + * daemon: add basic support for sd_is_socket_sockaddr + * daemon: add wrapper for sd_is_socket_sockaddr and tests + * daemon: properly skip sd_is_socket_sockaddr calls if not available + * Fix handling of addresses without port and add tests + * Fix styling to match PEP8 in most places + * Improve test skipping on old systems + * Include all fields from record + * journal: do not convert extra args to string in JournalHandler + * journal: fix repr of JournalHandler to match python3.6 + * journal: improve docstring formatting a bit + * journal: rename SENDER_FUNCTION to sender_function + * Makefile: add "doc" target for convenience + * Makefile: add convenience "shell" target to start python shell + * Makefile: remove unneeded -I/usr/include from flags + * Makefile: use $(INCLUDE_DIR) also for compilation + * Prevent non-str values from being concatenated with + + * Python 3.6 invalid escape sequence deprecation fixes + * Remove mid from JournalHandler + * replace dict.iteritems() with dict.items() to support py3 + * setup.py: allow LIBSYSTEMD_VERSION to be overridden + * test_daemon: xfail test_notify_with_socket if bind() fails + * test_journal: add tests for MESSAGE_ID passing + * tests: move login tests from doctest to separate file + * tests: skip journal.stream tests on ENOENT error + * Update to constants from systemd-233 + * util: add compatibility for old glibc + +------------------------------------------------------------------- Old: ---- python-systemd-233.tar.gz New: ---- exclude-tests-on-obs.patch python-systemd-234.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-systemd.spec ++++++ --- /var/tmp/diff_new_pack.2kIhLL/_old 2017-07-04 11:56:24.774099498 +0200 +++ /var/tmp/diff_new_pack.2kIhLL/_new 2017-07-04 11:56:24.778098936 +0200 @@ -17,13 +17,15 @@ Name: python-systemd -Version: 233 +Version: 234 Release: 0 Summary: Python wrappers for systemd functionality License: LGPL-2.1+ Group: Development/Languages/Python Url: https://github.com/systemd/python-systemd Source: https://github.com/systemd/%{name}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz +# PATCH-FIX-OPENSUSE exclude-tests-on-obs.patch removes a test when running tests at OBS. Should be removed as soon as OBS is fixed +Patch100: exclude-tests-on-obs.patch BuildRequires: fdupes BuildRequires: gcc-c++ BuildRequires: pkgconfig @@ -35,9 +37,10 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build %package doc -Summary: Documentation for %name +Summary: Documentation for python-systemd +# FIXME: use correct group, see "https://en.opensuse.org/openSUSE:Package_group_guidelines" Group: Documentation -Requires: %name = %version +Requires: %{name} = %{version} %description Python module for native access to the systemd facilities. Functionality is seperated into a number of modules: @@ -47,24 +50,23 @@ * systemd.login wraps parts of libsystemd used to query logged in users and available seats and machines. %description doc -Documentation and help files for %name +Documentation and help files for python-systemd. %prep %setup -q +%patch100 -p1 %build make %{?_smp_mflags} build -make sphinx-html -%{__rm} -r build/html/.buildinfo build/html/.doctrees build/html/_sources +make %{?_smp_mflags} sphinx-html +rm -r build/html/.buildinfo build/html/.doctrees build/html/_sources %install %make_install %fdupes %{buildroot}/%{python_sitearch} %check -# run doc-tests only when socket is available -test -f /run/systemd/journal/stdout || sed -i 's/--doctest[^ ]*//g' pytest.ini -make %{?_smp_mflags} check || : +make %{?_smp_mflags} check %files %defattr(-,root,root,-) @@ -72,6 +74,7 @@ %{python_sitearch}/* %files doc +%defattr(-,root,root) %doc build/html %changelog ++++++ exclude-tests-on-obs.patch ++++++ diff -ur python-systemd-234-orig/systemd/test/test_journal.py python-systemd-234/systemd/test/test_journal.py --- python-systemd-234-orig/systemd/test/test_journal.py 2017-03-26 03:33:59.000000000 +0200 +++ python-systemd-234/systemd/test/test_journal.py 2017-06-26 11:15:19.961627278 +0200 @@ -215,12 +215,12 @@ j.this_boot(TEST_MID) j.this_boot(TEST_MID.hex) -def test_reader_this_machine(tmpdir): - j = journal.Reader(path=tmpdir.strpath) - with j: - j.this_machine() - j.this_machine(TEST_MID) - j.this_machine(TEST_MID.hex) +#def test_reader_this_machine(tmpdir): +# j = journal.Reader(path=tmpdir.strpath) +# with j: +# j.this_machine() +# j.this_machine(TEST_MID) +# j.this_machine(TEST_MID.hex) def test_reader_query_unique(tmpdir): j = journal.Reader(path=tmpdir.strpath) ++++++ python-systemd-233.tar.gz -> python-systemd-234.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/Makefile new/python-systemd-234/Makefile --- old/python-systemd-233/Makefile 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/Makefile 2017-03-26 03:33:59.000000000 +0200 @@ -3,6 +3,7 @@ SPHINX_BUILD = sphinx-build ETAGS = etags INCLUDE_DIR := $(shell pkg-config --variable=includedir libsystemd) +INCLUDE_FLAGS := $(shell pkg-config --cflags libsystemd) VERSION := $(shell $(PYTHON) setup.py --version) TESTFLAGS = -v @@ -16,9 +17,8 @@ all: build .PHONY: update-constants -update-constants: $(INCLUDE_DIR)/systemd/sd-messages.h - cat $< systemd/id128-defines.h | \ - $(SED) -n -r '/#define SD_MESSAGE_[A-Z0-9_]/p' | \ +update-constants: update-constants.py $(INCLUDE_DIR)/systemd/sd-messages.h + $(PYTHON) $+ systemd/id128-defines.h | \ sort -u | \ tee systemd/id128-defines.h.tmp | \ $(SED) -n -r 's/,//g; s/#define (SD_MESSAGE_[A-Z0-9_]+)\s.*/add_id(m, "\1", \1) JOINER/p' | \ @@ -31,6 +31,7 @@ mv docs/id128.rst{.tmp,} build: + $(PYTHON) setup.py build_ext $(INCLUDE_FLAGS) $(PYTHON) setup.py build install: @@ -39,6 +40,9 @@ dist: $(PYTHON) setup.py sdist +sign: dist/systemd-python-$(VERSION).tar.gz + gpg --detach-sign -a dist/systemd-python-$(VERSION).tar.gz + clean: rm -rf build systemd/*.so systemd/*.py[co] *.py[co] systemd/__pycache__ @@ -50,6 +54,8 @@ PYTHONPATH=$(builddir) $(SPHINX_BUILD) -b $* $(SPHINXOPTS) docs build/$* @echo Output has been generated in build/$* +doc: sphinx-html + check: build (cd $(builddir) && $(PYTHON) -m pytest . ../../docs $(TESTFLAGS)) @@ -57,7 +63,14 @@ doc-sync: rsync -rlv --delete --omit-dir-times build/html/ $(www_target)/ +upload: dist/systemd-python-$(VERSION).tar.gz dist/systemd-python-$(VERSION).tar.gz.asc + twine-3 upload $+ + TAGS: $(shell git ls-files systemd/*.[ch]) $(ETAGS) $+ -.PHONY: build install dist clean distclean TAGS doc-sync +shell: +# we change the directory because python insists on adding $CWD to path + (cd $(builddir) && $(PYTHON)) + +.PHONY: build install dist sign upload clean distclean TAGS doc doc-sync shell diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/NEWS new/python-systemd-234/NEWS --- old/python-systemd-233/NEWS 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/NEWS 2017-03-26 03:33:59.000000000 +0200 @@ -1,5 +1,22 @@ Python wrappers for libsystemd API +CHANGES WITH 234: + + * Support for the new sd_is_socket_sockaddr added in systemd 233 + is added. + + * New id128 constants added in systemd 233 are included. + + * "Extra" fields for the log entry can be passed during + LoggerAdapter initialization or for each message separately. + Fields specified for the message have higher priority. + + * Small fixes and style tweaks all over. + + Contributions from: Park Jeongsoo, Jimmy Cao, Johannes + Weberhofer, Mike Gilbert, Oleksii Shevchuk, Ville Skyttä, + Wesley Bowman, Zbigniew Jędrzejewski-Szmek + CHANGES WITH 233: * Tests are fixed and should pass on various old and new @@ -11,7 +28,6 @@ Contributions from Robert James Hernandez, Zbigniew Jędrzejewski-Szmek - CHANGES WITH 232: * Wrappers for sd_journal_enumerate_unique, has_runtime_files, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/README.md new/python-systemd-234/README.md --- old/python-systemd-233/README.md 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/README.md 2017-03-26 03:33:59.000000000 +0200 @@ -25,6 +25,10 @@ apt-get install python-systemd python3-systemd +On openSUSE and SLE + + zypper in python-systemd + To build from source On Fedora 21+ with Python 2: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/docs/id128.rst new/python-systemd-234/docs/id128.rst --- old/python-systemd-233/docs/id128.rst 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/docs/id128.rst 2017-03-26 03:33:59.000000000 +0200 @@ -7,6 +7,7 @@ :inherited-members: .. autogenerated, do not edit! + .. autoattribute:: systemd.id128.SD_MESSAGE_BACKTRACE .. autoattribute:: systemd.id128.SD_MESSAGE_BOOTCHART .. autoattribute:: systemd.id128.SD_MESSAGE_CONFIG_ERROR .. autoattribute:: systemd.id128.SD_MESSAGE_COREDUMP @@ -49,3 +50,4 @@ .. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STARTING .. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STOPPED .. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STOPPING + .. autoattribute:: systemd.id128.SD_MESSAGE_USER_STARTUP_FINISHED diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/docs/login.rst new/python-systemd-234/docs/login.rst --- old/python-systemd-233/docs/login.rst 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/docs/login.rst 2017-03-26 03:33:59.000000000 +0200 @@ -17,12 +17,12 @@ >>> import select >>> from systemd import login - >>> m = login.Monitor("machine") + >>> m = login.Monitor("machine") # doctest: +SKIP >>> p = select.poll() - >>> p.register(m, m.get_events()) + >>> p.register(m, m.get_events()) # doctest: +SKIP >>> login.machine_names() # doctest: +SKIP [] >>> p.poll() # doctest: +SKIP [(3, 1)] >>> login.machine_names() # doctest: +SKIP - ['fedora-19.nspawn'] + ['fedora-25'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/setup.py new/python-systemd-234/setup.py --- old/python-systemd-233/setup.py 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/setup.py 2017-03-26 03:33:59.000000000 +0200 @@ -12,6 +12,7 @@ return cmd.returncode, cmd.stderr.read() def pkgconfig(package, **kw): + pkg_version = package.replace('-', '_').upper() + '_VERSION' flag_map = {'-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries'} pkgconf = os.getenv('PKG_CONFIG', 'pkg-config') status, result = call(pkgconf, '--libs', '--cflags', package) @@ -19,9 +20,13 @@ return status, result for token in result.split(): kw.setdefault(flag_map.get(token[:2]), []).append(token[2:]) - version = check_output([pkgconf, '--modversion', package], - universal_newlines=True).strip() - pair = (package.replace('-', '_').upper() + '_VERSION', version) + + # allow version detection to be overriden using environment variables + version = os.getenv(pkg_version) + if not version: + version = check_output([pkgconf, '--modversion', package], + universal_newlines=True).strip() + pair = (pkg_version, version) defines = kw.setdefault('define_macros', []) if pair not in defines: defines.append(pair) @@ -40,7 +45,7 @@ + '\n'.join(results) + '\n') sys.exit(status) -version = '233' +version = '234' defines = {'define_macros':[('PACKAGE_VERSION', '"{}"'.format(version))]} _journal = Extension('systemd/_journal', @@ -56,7 +61,8 @@ **lib('libsystemd', 'libsystemd-journal', **defines)) _daemon = Extension('systemd/_daemon', sources = ['systemd/_daemon.c', - 'systemd/pyutil.c'], + 'systemd/pyutil.c', + 'systemd/util.c'], extra_compile_args=['-Werror=implicit-function-declaration'], **lib('libsystemd', 'libsystemd-daemon', **defines)) id128 = Extension('systemd/id128', @@ -86,7 +92,9 @@ 'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)', ], py_modules = ['systemd.journal', 'systemd.daemon', - 'systemd.test.test_daemon', 'systemd.test.test_journal'], + 'systemd.test.test_daemon', + 'systemd.test.test_journal', + 'systemd.test.test_login'], ext_modules = [_journal, _reader, _daemon, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/systemd/_daemon.c new/python-systemd-234/systemd/_daemon.c --- old/python-systemd-233/systemd/_daemon.c 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/systemd/_daemon.c 2017-03-26 03:33:59.000000000 +0200 @@ -2,7 +2,7 @@ /*** - Copyright 2013 Zbigniew Jędrzejewski-Szmek <[email protected]> + Copyright 2013-2016 Zbigniew Jędrzejewski-Szmek <[email protected]> python-systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -31,12 +31,18 @@ #include "systemd/sd-daemon.h" #include "pyutil.h" #include "macro.h" +#include "util.h" #if LIBSYSTEMD_VERSION >= 214 # define HAVE_PID_NOTIFY -# if LIBSYSTEMD_VERSION >= 219 -# define HAVE_PID_NOTIFY_WITH_FDS -# endif +#endif + +#if LIBSYSTEMD_VERSION >= 219 +# define HAVE_PID_NOTIFY_WITH_FDS +#endif + +#if LIBSYSTEMD_VERSION >= 233 +# define HAVE_IS_SOCKET_SOCKADDR #endif PyDoc_STRVAR(module__doc__, @@ -145,14 +151,14 @@ #ifdef HAVE_PID_NOTIFY r = sd_pid_notify(pid, unset, msg); #else - PyErr_SetString(PyExc_NotImplementedError, "Compiled without support for sd_pid_notify"); + set_error(-ENOSYS, NULL, "Compiled without support for sd_pid_notify"); return NULL; #endif } else { #ifdef HAVE_PID_NOTIFY_WITH_FDS r = sd_pid_notify_with_fds(pid, unset, msg, arr, n_fds); #else - PyErr_SetString(PyExc_NotImplementedError, "Compiled without support for sd_pid_notify_with_fds"); + set_error(-ENOSYS, NULL, "Compiled without support for sd_pid_notify_with_fds"); return NULL; #endif } @@ -311,6 +317,60 @@ return PyBool_FromLong(r); } +PyDoc_STRVAR(is_socket_sockaddr__doc__, + "_is_socket_sockaddr(fd, address, type=0, flowinfo=0, listening=-1) -> bool\n\n" + "Wraps sd_is_socket_inet_sockaddr(3).\n" +#ifdef HAVE_IS_SOCKET_SOCKADDR + "`address` is a systemd-style numerical IPv4 or IPv6 address as used in\n" + "ListenStream=. A port may be included after a colon (\":\"). See\n" + "systemd.socket(5) for details.\n\n" + "Constants for `family` are defined in the socket module." +#else + "NOT SUPPORTED: compiled without support sd_socket_sockaddr" +#endif +); + +static PyObject* is_socket_sockaddr(PyObject *self, PyObject *args) { + int r; + int fd, type = 0, flowinfo = 0, listening = -1; + const char *address; + union sockaddr_union addr = {}; + unsigned addr_len; + + if (!PyArg_ParseTuple(args, "is|iii:_is_socket_sockaddr", + &fd, + &address, + &type, + &flowinfo, + &listening)) + return NULL; + + r = parse_sockaddr(address, &addr, &addr_len); + if (r < 0) { + set_error(r, NULL, "Cannot parse address"); + return NULL; + } + + if (flowinfo != 0) { + if (addr.sa.sa_family != AF_INET6) { + set_error(-EINVAL, NULL, "flowinfo is only applicable to IPv6 addresses"); + return NULL; + } + + addr.in6.sin6_flowinfo = flowinfo; + } + +#ifdef HAVE_IS_SOCKET_SOCKADDR + r = sd_is_socket_sockaddr(fd, type, &addr.sa, addr_len, listening); + if (set_error(r, NULL, NULL) < 0) + return NULL; + + return PyBool_FromLong(r); +#else + set_error(-ENOSYS, NULL, "Compiled without support for sd_is_socket_sockaddr"); + return NULL; +#endif +} PyDoc_STRVAR(is_socket_unix__doc__, "_is_socket_unix(fd, type, listening, path) -> bool\n\n" @@ -355,8 +415,9 @@ { "_is_mq", is_mq, METH_VARARGS, is_mq__doc__}, { "_is_socket", is_socket, METH_VARARGS, is_socket__doc__}, { "_is_socket_inet", is_socket_inet, METH_VARARGS, is_socket_inet__doc__}, + { "_is_socket_sockaddr", is_socket_sockaddr, METH_VARARGS, is_socket_sockaddr__doc__}, { "_is_socket_unix", is_socket_unix, METH_VARARGS, is_socket_unix__doc__}, - { NULL, NULL, 0, NULL } /* Sentinel */ + {} /* Sentinel */ }; #if PY_MAJOR_VERSION < 3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/systemd/_reader.c new/python-systemd-234/systemd/_reader.c --- old/python-systemd-233/systemd/_reader.c 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/systemd/_reader.c 2017-03-26 03:33:59.000000000 +0200 @@ -1048,7 +1048,7 @@ _value_set = NULL; return value_set; #else - set_error(-ENOSYS, NULL, "Not implemented"); + set_error(-ENOSYS, NULL, "Compiled without support for sd_journal_enumerate_fields"); return NULL; #endif } @@ -1069,7 +1069,7 @@ return PyBool_FromLong(r); #else - set_error(-ENOSYS, NULL, "Not implemented"); + set_error(-ENOSYS, NULL, "Compiled without support for sd_journal_has_runtime_files"); return NULL; #endif } @@ -1090,7 +1090,7 @@ return PyBool_FromLong(r); #else - set_error(-ENOSYS, NULL, "Not implemented"); + set_error(-ENOSYS, NULL, "Compiled without support for sd_journal_has_persistent_files"); return NULL; #endif } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/systemd/daemon.py new/python-systemd-234/systemd/daemon.py --- old/python-systemd-233/systemd/daemon.py 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/systemd/daemon.py 2017-03-26 03:33:59.000000000 +0200 @@ -1,3 +1,5 @@ +from socket import AF_UNSPEC as _AF_UNSPEC + from ._daemon import (__version__, booted, notify, @@ -5,10 +7,10 @@ _is_fifo, _is_socket, _is_socket_inet, + _is_socket_sockaddr, _is_socket_unix, _is_mq, LISTEN_FDS_START) -from socket import AF_UNSPEC as _AF_UNSPEC def _convert_fileobj(fileobj): try: @@ -28,6 +30,20 @@ fd = _convert_fileobj(fileobj) return _is_socket_inet(fd, family, type, listening, port) +def is_socket_sockaddr(fileobj, address, type=0, flowinfo=0, listening=-1): + """Check socket type, address and/or port, flowinfo, listening state. + + Wraps sd_is_socket_inet_sockaddr(3). + + `address` is a systemd-style numerical IPv4 or IPv6 address as used in + ListenStream=. A port may be included after a colon (":"). + See systemd.socket(5) for details. + + Constants for `family` are defined in the socket module. + """ + fd = _convert_fileobj(fileobj) + return _is_socket_sockaddr(fd, address, type, flowinfo, listening) + def is_socket_unix(fileobj, type=0, listening=-1, path=None): fd = _convert_fileobj(fileobj) return _is_socket_unix(fd, type, listening, path) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/systemd/id128-constants.h new/python-systemd-234/systemd/id128-constants.h --- old/python-systemd-233/systemd/id128-constants.h 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/systemd/id128-constants.h 2017-03-26 03:33:59.000000000 +0200 @@ -1,3 +1,4 @@ +add_id(m, "SD_MESSAGE_BACKTRACE", SD_MESSAGE_BACKTRACE) JOINER add_id(m, "SD_MESSAGE_BOOTCHART", SD_MESSAGE_BOOTCHART) JOINER add_id(m, "SD_MESSAGE_CONFIG_ERROR", SD_MESSAGE_CONFIG_ERROR) JOINER add_id(m, "SD_MESSAGE_COREDUMP", SD_MESSAGE_COREDUMP) JOINER @@ -40,3 +41,4 @@ add_id(m, "SD_MESSAGE_UNIT_STARTING", SD_MESSAGE_UNIT_STARTING) JOINER add_id(m, "SD_MESSAGE_UNIT_STOPPED", SD_MESSAGE_UNIT_STOPPED) JOINER add_id(m, "SD_MESSAGE_UNIT_STOPPING", SD_MESSAGE_UNIT_STOPPING) JOINER +add_id(m, "SD_MESSAGE_USER_STARTUP_FINISHED", SD_MESSAGE_USER_STARTUP_FINISHED) JOINER diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/systemd/id128-defines.h new/python-systemd-234/systemd/id128-defines.h --- old/python-systemd-233/systemd/id128-defines.h 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/systemd/id128-defines.h 2017-03-26 03:33:59.000000000 +0200 @@ -1,42 +1,44 @@ -#define SD_MESSAGE_BOOTCHART SD_ID128_MAKE(9f,26,aa,56,2c,f4,40,c2,b1,6c,77,3d,04,79,b5,18) -#define SD_MESSAGE_CONFIG_ERROR SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01) -#define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1) +#define SD_MESSAGE_BACKTRACE SD_ID128_MAKE(1f,4e,0a,44,a8,86,49,93,9a,ae,a3,4f,c6,da,8c,95) +#define SD_MESSAGE_BOOTCHART SD_ID128_MAKE(9f,26,aa,56,2c,f4,40,c2,b1,6c,77,3d,04,79,b5,18) +#define SD_MESSAGE_CONFIG_ERROR SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01) +#define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1) #define SD_MESSAGE_DNSSEC_DOWNGRADE SD_ID128_MAKE(36,db,2d,fa,5a,90,45,e1,bd,4a,f5,f9,3e,1c,f0,57) -#define SD_MESSAGE_DNSSEC_FAILURE SD_ID128_MAKE(16,75,d7,f1,72,17,40,98,b1,10,8b,f8,c7,dc,8f,5d) +#define SD_MESSAGE_DNSSEC_FAILURE SD_ID128_MAKE(16,75,d7,f1,72,17,40,98,b1,10,8b,f8,c7,dc,8f,5d) #define SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED SD_ID128_MAKE(4d,44,08,cf,d0,d1,44,85,91,84,d1,e6,5d,7c,8a,65) #define SD_MESSAGE_FORWARD_SYSLOG_MISSED SD_ID128_MAKE(00,27,22,9c,a0,64,41,81,a7,6c,4e,92,45,8a,fa,2e) -#define SD_MESSAGE_HIBERNATE_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73) +#define SD_MESSAGE_HIBERNATE_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73) #define SD_MESSAGE_INVALID_CONFIGURATION SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01) -#define SD_MESSAGE_JOURNAL_DROPPED SD_ID128_MAKE(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e) -#define SD_MESSAGE_JOURNAL_MISSED SD_ID128_MAKE(e9,bf,28,e6,e8,34,48,1b,b6,f4,8f,54,8a,d1,36,06) -#define SD_MESSAGE_JOURNAL_START SD_ID128_MAKE(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b) -#define SD_MESSAGE_JOURNAL_STOP SD_ID128_MAKE(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b) -#define SD_MESSAGE_JOURNAL_USAGE SD_ID128_MAKE(ec,38,7f,57,7b,84,4b,8f,a9,48,f3,3c,ad,9a,75,e6) -#define SD_MESSAGE_LID_CLOSED SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,70) -#define SD_MESSAGE_LID_OPENED SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,6f) -#define SD_MESSAGE_MACHINE_START SD_ID128_MAKE(24,d8,d4,45,25,73,40,24,96,06,83,81,a6,31,2d,f2) -#define SD_MESSAGE_MACHINE_STOP SD_ID128_MAKE(58,43,2b,d3,ba,ce,47,7c,b5,14,b5,63,81,b8,a7,58) -#define SD_MESSAGE_OVERMOUNTING SD_ID128_MAKE(1d,ee,03,69,c7,fc,47,36,b7,09,9b,38,ec,b4,6e,e7) -#define SD_MESSAGE_POWER_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71) -#define SD_MESSAGE_SEAT_START SD_ID128_MAKE(fc,be,fc,5d,a2,3d,42,80,93,f9,7c,82,a9,29,0f,7b) -#define SD_MESSAGE_SEAT_STOP SD_ID128_MAKE(e7,85,2b,fe,46,78,4e,d0,ac,cd,e0,4b,c8,64,c2,d5) -#define SD_MESSAGE_SESSION_START SD_ID128_MAKE(8d,45,62,0c,1a,43,48,db,b1,74,10,da,57,c6,0c,66) -#define SD_MESSAGE_SESSION_STOP SD_ID128_MAKE(33,54,93,94,24,b4,45,6d,98,02,ca,83,33,ed,42,4a) -#define SD_MESSAGE_SHUTDOWN SD_ID128_MAKE(98,26,88,66,d1,d5,4a,49,9c,4e,98,92,1d,93,bc,40) -#define SD_MESSAGE_SLEEP_START SD_ID128_MAKE(6b,bd,95,ee,97,79,41,e4,97,c4,8b,e2,7c,25,41,28) -#define SD_MESSAGE_SLEEP_STOP SD_ID128_MAKE(88,11,e6,df,2a,8e,40,f5,8a,94,ce,a2,6f,8e,bf,14) -#define SD_MESSAGE_SPAWN_FAILED SD_ID128_MAKE(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7) +#define SD_MESSAGE_JOURNAL_DROPPED SD_ID128_MAKE(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e) +#define SD_MESSAGE_JOURNAL_MISSED SD_ID128_MAKE(e9,bf,28,e6,e8,34,48,1b,b6,f4,8f,54,8a,d1,36,06) +#define SD_MESSAGE_JOURNAL_START SD_ID128_MAKE(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b) +#define SD_MESSAGE_JOURNAL_STOP SD_ID128_MAKE(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b) +#define SD_MESSAGE_JOURNAL_USAGE SD_ID128_MAKE(ec,38,7f,57,7b,84,4b,8f,a9,48,f3,3c,ad,9a,75,e6) +#define SD_MESSAGE_LID_CLOSED SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,70) +#define SD_MESSAGE_LID_OPENED SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,6f) +#define SD_MESSAGE_MACHINE_START SD_ID128_MAKE(24,d8,d4,45,25,73,40,24,96,06,83,81,a6,31,2d,f2) +#define SD_MESSAGE_MACHINE_STOP SD_ID128_MAKE(58,43,2b,d3,ba,ce,47,7c,b5,14,b5,63,81,b8,a7,58) +#define SD_MESSAGE_OVERMOUNTING SD_ID128_MAKE(1d,ee,03,69,c7,fc,47,36,b7,09,9b,38,ec,b4,6e,e7) +#define SD_MESSAGE_POWER_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71) +#define SD_MESSAGE_SEAT_START SD_ID128_MAKE(fc,be,fc,5d,a2,3d,42,80,93,f9,7c,82,a9,29,0f,7b) +#define SD_MESSAGE_SEAT_STOP SD_ID128_MAKE(e7,85,2b,fe,46,78,4e,d0,ac,cd,e0,4b,c8,64,c2,d5) +#define SD_MESSAGE_SESSION_START SD_ID128_MAKE(8d,45,62,0c,1a,43,48,db,b1,74,10,da,57,c6,0c,66) +#define SD_MESSAGE_SESSION_STOP SD_ID128_MAKE(33,54,93,94,24,b4,45,6d,98,02,ca,83,33,ed,42,4a) +#define SD_MESSAGE_SHUTDOWN SD_ID128_MAKE(98,26,88,66,d1,d5,4a,49,9c,4e,98,92,1d,93,bc,40) +#define SD_MESSAGE_SLEEP_START SD_ID128_MAKE(6b,bd,95,ee,97,79,41,e4,97,c4,8b,e2,7c,25,41,28) +#define SD_MESSAGE_SLEEP_STOP SD_ID128_MAKE(88,11,e6,df,2a,8e,40,f5,8a,94,ce,a2,6f,8e,bf,14) +#define SD_MESSAGE_SPAWN_FAILED SD_ID128_MAKE(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7) #define SD_MESSAGE_STARTUP_FINISHED SD_ID128_MAKE(b0,7a,24,9c,d0,24,41,4a,82,dd,00,cd,18,13,78,ff) -#define SD_MESSAGE_SUSPEND_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72) -#define SD_MESSAGE_SYSTEM_DOCKED SD_ID128_MAKE(f5,f4,16,b8,62,07,4b,28,92,7a,48,c3,ba,7d,51,ff) -#define SD_MESSAGE_SYSTEM_UNDOCKED SD_ID128_MAKE(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53) -#define SD_MESSAGE_TIME_CHANGE SD_ID128_MAKE(c7,a7,87,07,9b,35,4e,aa,a9,e7,7b,37,18,93,cd,27) -#define SD_MESSAGE_TIMEZONE_CHANGE SD_ID128_MAKE(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90) -#define SD_MESSAGE_TRUNCATED_CORE SD_ID128_MAKE(5a,ad,d8,e9,54,dc,4b,1a,8c,95,4d,63,fd,9e,11,37) -#define SD_MESSAGE_UNIT_FAILED SD_ID128_MAKE(be,02,cf,68,55,d2,42,8b,a4,0d,f7,e9,d0,22,f0,3d) -#define SD_MESSAGE_UNIT_RELOADED SD_ID128_MAKE(7b,05,eb,c6,68,38,42,22,ba,a8,88,11,79,cf,da,54) -#define SD_MESSAGE_UNIT_RELOADING SD_ID128_MAKE(d3,4d,03,7f,ff,18,47,e6,ae,66,9a,37,0e,69,47,25) -#define SD_MESSAGE_UNIT_STARTED SD_ID128_MAKE(39,f5,34,79,d3,a0,45,ac,8e,11,78,62,48,23,1f,bf) -#define SD_MESSAGE_UNIT_STARTING SD_ID128_MAKE(7d,49,58,e8,42,da,4a,75,8f,6c,1c,dc,7b,36,dc,c5) -#define SD_MESSAGE_UNIT_STOPPED SD_ID128_MAKE(9d,1a,aa,27,d6,01,40,bd,96,36,54,38,aa,d2,02,86) -#define SD_MESSAGE_UNIT_STOPPING SD_ID128_MAKE(de,5b,42,6a,63,be,47,a7,b6,ac,3e,aa,c8,2e,2f,6f) +#define SD_MESSAGE_SUSPEND_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72) +#define SD_MESSAGE_SYSTEM_DOCKED SD_ID128_MAKE(f5,f4,16,b8,62,07,4b,28,92,7a,48,c3,ba,7d,51,ff) +#define SD_MESSAGE_SYSTEM_UNDOCKED SD_ID128_MAKE(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53) +#define SD_MESSAGE_TIME_CHANGE SD_ID128_MAKE(c7,a7,87,07,9b,35,4e,aa,a9,e7,7b,37,18,93,cd,27) +#define SD_MESSAGE_TIMEZONE_CHANGE SD_ID128_MAKE(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90) +#define SD_MESSAGE_TRUNCATED_CORE SD_ID128_MAKE(5a,ad,d8,e9,54,dc,4b,1a,8c,95,4d,63,fd,9e,11,37) +#define SD_MESSAGE_UNIT_FAILED SD_ID128_MAKE(be,02,cf,68,55,d2,42,8b,a4,0d,f7,e9,d0,22,f0,3d) +#define SD_MESSAGE_UNIT_RELOADED SD_ID128_MAKE(7b,05,eb,c6,68,38,42,22,ba,a8,88,11,79,cf,da,54) +#define SD_MESSAGE_UNIT_RELOADING SD_ID128_MAKE(d3,4d,03,7f,ff,18,47,e6,ae,66,9a,37,0e,69,47,25) +#define SD_MESSAGE_UNIT_STARTED SD_ID128_MAKE(39,f5,34,79,d3,a0,45,ac,8e,11,78,62,48,23,1f,bf) +#define SD_MESSAGE_UNIT_STARTING SD_ID128_MAKE(7d,49,58,e8,42,da,4a,75,8f,6c,1c,dc,7b,36,dc,c5) +#define SD_MESSAGE_UNIT_STOPPED SD_ID128_MAKE(9d,1a,aa,27,d6,01,40,bd,96,36,54,38,aa,d2,02,86) +#define SD_MESSAGE_UNIT_STOPPING SD_ID128_MAKE(de,5b,42,6a,63,be,47,a7,b6,ac,3e,aa,c8,2e,2f,6f) +#define SD_MESSAGE_USER_STARTUP_FINISHED SD_ID128_MAKE(ee,d0,0a,68,ff,d8,4e,31,88,21,05,fd,97,3a,bd,d1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/systemd/journal.py new/python-systemd-234/systemd/journal.py --- old/python-systemd-233/systemd/journal.py 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/systemd/journal.py 2017-03-26 03:33:59.000000000 +0200 @@ -26,10 +26,11 @@ import traceback as _traceback import os as _os import logging as _logging -if _sys.version_info >= (3,3): - from collections import ChainMap as _ChainMap from syslog import (LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG) +if _sys.version_info >= (3,3): + from collections import ChainMap as _ChainMap + from ._journal import __version__, sendv, stream_fd from ._reader import (_Reader, NOP, APPEND, INVALIDATE, LOCAL_ONLY, RUNTIME_ONLY, @@ -43,19 +44,24 @@ else: Monotonic = tuple + def _convert_monotonic(m): return Monotonic((_datetime.timedelta(microseconds=m[0]), _uuid.UUID(bytes=m[1]))) + def _convert_source_monotonic(s): return _datetime.timedelta(microseconds=int(s)) + def _convert_realtime(t): return _datetime.datetime.fromtimestamp(t / 1000000) + def _convert_timestamp(s): return _datetime.datetime.fromtimestamp(int(s) / 1000000) + def _convert_trivial(x): return x @@ -103,9 +109,11 @@ _IDENT_CHARACTER = set('ABCDEFGHIJKLMNOPQRTSUVWXYZ_0123456789') + def _valid_field_name(s): return not (set(s) - _IDENT_CHARACTER) + class Reader(_Reader): """Access systemd journal entries. @@ -164,7 +172,7 @@ flags = 0 super(Reader, self).__init__(flags, path, files) - if _sys.version_info >= (3,3): + if _sys.version_info >= (3, 3): self.converters = _ChainMap() if converters is not None: self.converters.maps.append(converters) @@ -225,8 +233,8 @@ def add_match(self, *args, **kwargs): """Add one or more matches to the filter journal log entries. - All matches of different field are combined in a logical AND, and - matches of the same field are automatically combined in a logical OR. + All matches of different field are combined with logical AND, and + matches of the same field are automatically combined with logical OR. Matches can be passed as strings of form "FIELD=value", or keyword arguments FIELD="value". """ @@ -236,12 +244,12 @@ super(Reader, self).add_match(arg) def get_next(self, skip=1): - """Return the next log entry as a dictionary. + r"""Return the next log entry as a dictionary. Entries will be processed with converters specified during Reader creation. - Optional skip value will return the `skip`\-th log entry. + Optional `skip` value will return the `skip`-th log entry. Currently a standard dictionary of fields is returned, but in the future this might be changed to a different mapping type, so the @@ -257,11 +265,11 @@ return dict() def get_previous(self, skip=1): - """Return the previous log entry. + r"""Return the previous log entry. Equivalent to get_next(-skip). - Optional skip value will return the -`skip`\-th log entry. + Optional `skip` value will return the -`skip`-th log entry. Entries will be processed with converters specified during Reader creation. @@ -391,13 +399,15 @@ mid = mid.hex return _get_catalog(mid) + def _make_line(field, value): if isinstance(value, bytes): return field.encode('utf-8') + b'=' + value - elif isinstance(value, int): - return field + '=' + str(value) - else: + elif isinstance(value, str): return field + '=' + value + else: + return field + '=' + str(value) + def send(MESSAGE, MESSAGE_ID=None, CODE_FILE=None, CODE_LINE=None, CODE_FUNC=None, @@ -434,7 +444,7 @@ id = getattr(MESSAGE_ID, 'hex', MESSAGE_ID) args.append('MESSAGE_ID=' + id) - if CODE_LINE == CODE_FILE == CODE_FUNC == None: + if CODE_LINE is CODE_FILE is CODE_FUNC is None: CODE_FILE, CODE_LINE, CODE_FUNC = _traceback.extract_stack(limit=2)[0][:3] if CODE_FILE is not None: args.append('CODE_FILE=' + CODE_FILE) @@ -446,6 +456,7 @@ args.extend(_make_line(key, val) for key, val in kwargs.items()) return sendv(*args) + def stream(identifier=None, priority=LOG_INFO, level_prefix=False): r"""Return a file object wrapping a stream to journal. @@ -456,8 +467,8 @@ newline character is written. >>> from systemd import journal - >>> stream = journal.stream('myapp') - >>> res = stream.write('message...\n') + >>> stream = journal.stream('myapp') # doctest: +SKIP + >>> res = stream.write('message...\n') # doctest: +SKIP will produce the following message in the journal:: @@ -470,8 +481,8 @@ This interface can be used conveniently with the print function: >>> from __future__ import print_function - >>> fileobj = journal.stream() - >>> print('message...', file=fileobj) # doctest: +SKIP + >>> stream = journal.stream() # doctest: +SKIP + >>> print('message...', file=stream) # doctest: +SKIP priority is the syslog priority, one of `LOG_EMERG`, `LOG_ALERT`, `LOG_CRIT`, `LOG_ERR`, `LOG_WARNING`, `LOG_NOTICE`, `LOG_INFO`, `LOG_DEBUG`. @@ -489,6 +500,7 @@ fd = stream_fd(identifier, priority, level_prefix) return _os.fdopen(fd, 'w', 1) + class JournalHandler(_logging.Handler): """Journal handler class for the Python logging framework. @@ -530,15 +542,18 @@ program: >>> JournalHandler(SYSLOG_IDENTIFIER='my-cool-app') - <systemd.journal.JournalHandler object at ...> + <...JournalHandler ...> The following journal fields will be sent: `MESSAGE`, `PRIORITY`, `THREAD_NAME`, `CODE_FILE`, `CODE_LINE`, `CODE_FUNC`, `LOGGER` (name as supplied to getLogger call), `MESSAGE_ID` (optional, see above), `SYSLOG_IDENTIFIER` (defaults to sys.argv[0]). + + The function used to actually send messages can be overridden using + the `sender_function` parameter. """ - def __init__(self, level=_logging.NOTSET, **kwargs): + def __init__(self, level=_logging.NOTSET, sender_function=send, **kwargs): super(JournalHandler, self).__init__(level) for name in kwargs: @@ -546,6 +561,8 @@ raise ValueError('Invalid field name: ' + name) if 'SYSLOG_IDENTIFIER' not in kwargs: kwargs['SYSLOG_IDENTIFIER'] = _sys.argv[0] + + self.send = sender_function self._extra = kwargs def emit(self, record): @@ -557,22 +574,37 @@ """ try: msg = self.format(record) - pri = self.mapPriority(record.levelno) - mid = getattr(record, 'MESSAGE_ID', None) - send(msg, - MESSAGE_ID=mid, - PRIORITY=format(pri), - LOGGER=record.name, - THREAD_NAME=record.threadName, - CODE_FILE=record.pathname, - CODE_LINE=record.lineno, - CODE_FUNC=record.funcName, - **self._extra) + pri = self.map_priority(record.levelno) + # defaults + extras = self._extra.copy() + + # higher priority + if record.exc_text: + extras['EXCEPTION_TEXT'] = record.exc_text + + if record.exc_info: + extras['EXCEPTION_INFO'] = record.exc_info + + if record.args: + extras['CODE_ARGS'] = str(record.args) + + # explicit arguments — highest priority + extras.update(record.__dict__) + + self.send(msg, + PRIORITY=format(pri), + LOGGER=record.name, + THREAD_NAME=record.threadName, + PROCESS_NAME=record.processName, + CODE_FILE=record.pathname, + CODE_LINE=record.lineno, + CODE_FUNC=record.funcName, + **extras) except Exception: self.handleError(record) @staticmethod - def mapPriority(levelno): + def map_priority(levelno): """Map logging levels to journald priorities. Since Python log level numbers are "sparse", we have to map numbers in @@ -590,3 +622,5 @@ return LOG_CRIT else: return LOG_ALERT + + mapPriority = map_priority diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/systemd/test/test_daemon.py new/python-systemd-234/systemd/test/test_daemon.py --- old/python-systemd-233/systemd/test/test_daemon.py 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/systemd/test/test_daemon.py 2017-03-26 03:33:59.000000000 +0200 @@ -9,6 +9,7 @@ is_socket, _is_socket, is_socket_inet, _is_socket_inet, is_socket_unix, _is_socket_unix, + is_socket_sockaddr, _is_socket_sockaddr, is_mq, _is_mq, listen_fds, notify) @@ -122,15 +123,21 @@ assert not is_fifo(sock) assert not is_mq_wrapper(sock) assert not is_socket_inet(sock) + with skip_enosys(): + assert not is_socket_sockaddr(sock, '127.0.0.1:2000') fd = sock.fileno() assert not is_fifo(fd) assert not is_mq_wrapper(fd) assert not is_socket_inet(fd) + with skip_enosys(): + assert not is_socket_sockaddr(fd, '127.0.0.1:2000') assert not _is_fifo(fd) assert not _is_mq_wrapper(fd) assert not _is_socket_inet(fd) + with skip_enosys(): + assert not _is_socket_sockaddr(fd, '127.0.0.1:2000') def test_is_socket(): with closing_socketpair(socket.AF_UNIX) as pair: @@ -141,12 +148,54 @@ assert not is_socket(arg, socket.AF_INET) assert is_socket(arg, socket.AF_UNIX, socket.SOCK_STREAM) assert not is_socket(arg, socket.AF_INET, socket.SOCK_DGRAM) + with skip_enosys(): + assert not is_socket_sockaddr(arg, '8.8.8.8:2000', socket.SOCK_DGRAM, 0, 0) - assert is_socket(sock) - assert is_socket(arg, socket.AF_UNIX) - assert not is_socket(arg, socket.AF_INET) - assert is_socket(arg, socket.AF_UNIX, socket.SOCK_STREAM) - assert not is_socket(arg, socket.AF_INET, socket.SOCK_DGRAM) + assert _is_socket(arg) + assert _is_socket(arg, socket.AF_UNIX) + assert not _is_socket(arg, socket.AF_INET) + assert _is_socket(arg, socket.AF_UNIX, socket.SOCK_STREAM) + assert not _is_socket(arg, socket.AF_INET, socket.SOCK_DGRAM) + with skip_enosys(): + assert not _is_socket_sockaddr(arg, '8.8.8.8:2000', socket.SOCK_DGRAM, 0, 0) + +def test_is_socket_sockaddr(): + with contextlib.closing(socket.socket(socket.AF_INET)) as sock: + sock.bind(('127.0.0.1', 0)) + addr, port = sock.getsockname() + port = ':{}'.format(port) + + for listening in (0, 1): + for arg in (sock, sock.fileno()): + with skip_enosys(): + assert is_socket_sockaddr(arg, '127.0.0.1', socket.SOCK_STREAM) + with skip_enosys(): + assert is_socket_sockaddr(arg, '127.0.0.1' + port, socket.SOCK_STREAM) + + with skip_enosys(): + assert is_socket_sockaddr(arg, '127.0.0.1' + port, listening=listening) + with skip_enosys(): + assert is_socket_sockaddr(arg, '127.0.0.1' + port, listening=-1) + with skip_enosys(): + assert not is_socket_sockaddr(arg, '127.0.0.1' + port, listening=not listening) + + with pytest.raises(ValueError): + is_socket_sockaddr(arg, '127.0.0.1', flowinfo=123456) + + with skip_enosys(): + assert not is_socket_sockaddr(arg, '129.168.11.11:23', socket.SOCK_STREAM) + with skip_enosys(): + assert not is_socket_sockaddr(arg, '127.0.0.1', socket.SOCK_DGRAM) + + with pytest.raises(ValueError): + _is_socket_sockaddr(arg, '127.0.0.1', 0, 123456) + + with skip_enosys(): + assert not _is_socket_sockaddr(arg, '129.168.11.11:23', socket.SOCK_STREAM) + with skip_enosys(): + assert not _is_socket_sockaddr(arg, '127.0.0.1', socket.SOCK_DGRAM) + + sock.listen(11) def test__is_socket(): with closing_socketpair(socket.AF_UNIX) as pair: @@ -208,12 +257,12 @@ assert listen_fds() == [] def test_notify_no_socket(): - assert notify('READY=1') == False + assert notify('READY=1') is False with skip_enosys(): - assert notify('FDSTORE=1', fds=[]) == False - assert notify('FDSTORE=1', fds=[1,2]) == False - assert notify('FDSTORE=1', pid=os.getpid()) == False - assert notify('FDSTORE=1', pid=os.getpid(), fds=(1,)) == False + assert notify('FDSTORE=1', fds=[]) is False + assert notify('FDSTORE=1', fds=[1, 2]) is False + assert notify('FDSTORE=1', pid=os.getpid()) is False + assert notify('FDSTORE=1', pid=os.getpid(), fds=(1,)) is False if sys.version_info >= (3,): connection_error = ConnectionRefusedError @@ -229,7 +278,7 @@ with skip_enosys(): notify('FDSTORE=1', fds=[]) with pytest.raises(connection_error): - notify('FDSTORE=1', fds=[1,2]) + notify('FDSTORE=1', fds=[1, 2]) with pytest.raises(connection_error): notify('FDSTORE=1', pid=os.getpid()) with pytest.raises(connection_error): @@ -238,15 +287,18 @@ def test_notify_with_socket(tmpdir): path = tmpdir.join('socket').strpath sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) - sock.bind(path) + try: + sock.bind(path) + except socket.error as e: + pytest.xfail('failed to bind socket (%s)' % e) # SO_PASSCRED is not defined in python2.7 SO_PASSCRED = getattr(socket, 'SO_PASSCRED', 16) sock.setsockopt(socket.SOL_SOCKET, SO_PASSCRED, 1) os.environ['NOTIFY_SOCKET'] = path - assert notify('READY=1') == True + assert notify('READY=1') with skip_enosys(): - assert notify('FDSTORE=1', fds=[]) == True - assert notify('FDSTORE=1', fds=[1,2]) == True - assert notify('FDSTORE=1', pid=os.getpid()) == True - assert notify('FDSTORE=1', pid=os.getpid(), fds=(1,)) == True + assert notify('FDSTORE=1', fds=[]) + assert notify('FDSTORE=1', fds=[1, 2]) + assert notify('FDSTORE=1', pid=os.getpid()) + assert notify('FDSTORE=1', pid=os.getpid(), fds=(1,)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/systemd/test/test_journal.py new/python-systemd-234/systemd/test/test_journal.py --- old/python-systemd-233/systemd/test/test_journal.py 2016-10-17 10:16:43.000000000 +0200 +++ new/python-systemd-234/systemd/test/test_journal.py 2017-03-26 03:33:59.000000000 +0200 @@ -1,3 +1,4 @@ +from __future__ import print_function import contextlib import datetime import errno @@ -5,19 +6,47 @@ import os import time import uuid +import traceback as _traceback from systemd import journal, id128 +from systemd.journal import _make_line import pytest TEST_MID = uuid.UUID('8441372f8dca4ca98694a6091fd8519f') +TEST_MID2 = uuid.UUID('8441370000000000000000001fd85000') + +class MockSender: + def __init__(self): + self.buf = [] + + def send(self, MESSAGE, MESSAGE_ID=None, + CODE_FILE=None, CODE_LINE=None, CODE_FUNC=None, + **kwargs): + args = ['MESSAGE=' + MESSAGE] + + if MESSAGE_ID is not None: + id = getattr(MESSAGE_ID, 'hex', MESSAGE_ID) + args.append('MESSAGE_ID=' + id) + + if CODE_LINE is CODE_FILE is CODE_FUNC is None: + CODE_FILE, CODE_LINE, CODE_FUNC = _traceback.extract_stack(limit=2)[0][:3] + if CODE_FILE is not None: + args.append('CODE_FILE=' + CODE_FILE) + if CODE_LINE is not None: + args.append('CODE_LINE={:d}'.format(CODE_LINE)) + if CODE_FUNC is not None: + args.append('CODE_FUNC=' + CODE_FUNC) + + args.extend(_make_line(key, val) for key, val in kwargs.items()) + self.buf.append(args) @contextlib.contextmanager -def skip_enosys(): +def skip_oserror(code): try: yield - except OSError as e: - if e.errno == errno.ENOSYS: + except (OSError, IOError) as e: + if e.errno == code: pytest.skip() raise @@ -29,7 +58,7 @@ pytest.skip() def test_priorities(): - p = journal.JournalHandler.mapPriority + p = journal.JournalHandler.map_priority assert p(logging.NOTSET) == journal.LOG_DEBUG assert p(logging.DEBUG) == journal.LOG_DEBUG @@ -58,6 +87,63 @@ kw = {'X':3, 'X3':4} journal.JournalHandler(logging.INFO, **kw) +def test_journalhandler_info(): + record = logging.LogRecord('test-logger', logging.INFO, 'testpath', 1, 'test', None, None) + + sender = MockSender() + kw = {'X':3, 'X3':4, 'sender_function': sender.send} + handler = journal.JournalHandler(logging.INFO, **kw) + handler.emit(record) + assert len(sender.buf) == 1 + assert 'X=3' in sender.buf[0] + assert 'X3=4' in sender.buf[0] + +def test_journalhandler_no_message_id(): + record = logging.LogRecord('test-logger', logging.INFO, 'testpath', 1, 'test', None, None) + sender = MockSender() + handler = journal.JournalHandler(logging.INFO, sender_function=sender.send) + handler.emit(record) + assert len(sender.buf) == 1 + assert all(not m.startswith('MESSAGE_ID=') for m in sender.buf[0]) + +def test_journalhandler_message_id_on_handler(): + record = logging.LogRecord('test-logger', logging.INFO, 'testpath', 1, 'test', None, None) + sender = MockSender() + handler = journal.JournalHandler(logging.INFO, sender_function=sender.send, + MESSAGE_ID=TEST_MID) + handler.emit(record) + assert len(sender.buf) == 1 + assert 'MESSAGE_ID=' + TEST_MID.hex in sender.buf[0] + +def test_journalhandler_message_id_on_handler_hex(): + record = logging.LogRecord('test-logger', logging.INFO, 'testpath', 1, 'test', None, None) + sender = MockSender() + handler = journal.JournalHandler(logging.INFO, sender_function=sender.send, + MESSAGE_ID=TEST_MID.hex) + handler.emit(record) + assert len(sender.buf) == 1 + assert 'MESSAGE_ID=' + TEST_MID.hex in sender.buf[0] + +def test_journalhandler_message_id_on_message(): + record = logging.LogRecord('test-logger', logging.INFO, 'testpath', 1, 'test', None, None) + record.__dict__['MESSAGE_ID'] = TEST_MID2 + sender = MockSender() + handler = journal.JournalHandler(logging.INFO, sender_function=sender.send, + MESSAGE_ID=TEST_MID) + handler.emit(record) + assert len(sender.buf) == 1 + assert 'MESSAGE_ID=' + TEST_MID2.hex in sender.buf[0] + +def test_journalhandler_message_id_on_message_hex(): + record = logging.LogRecord('test-logger', logging.INFO, 'testpath', 1, 'test', None, None) + record.__dict__['MESSAGE_ID'] = TEST_MID2.hex + sender = MockSender() + handler = journal.JournalHandler(logging.INFO, sender_function=sender.send, + MESSAGE_ID=TEST_MID) + handler.emit(record) + assert len(sender.buf) == 1 + assert 'MESSAGE_ID=' + TEST_MID2.hex in sender.buf[0] + def test_reader_init_flags(): j1 = journal.Reader() j2 = journal.Reader(journal.LOCAL_ONLY) @@ -96,7 +182,7 @@ def test_reader_init_path_fd(tmpdir): fd = os.open(tmpdir.strpath, os.O_RDONLY) - with skip_enosys(): + with skip_oserror(errno.ENOSYS): j1 = journal.Reader(path=fd) assert list(j1) == [] @@ -139,7 +225,7 @@ def test_reader_query_unique(tmpdir): j = journal.Reader(path=tmpdir.strpath) with j: - with skip_enosys(): + with skip_oserror(errno.ENOSYS): ans = j.query_unique('FOOBAR') assert isinstance(ans, set) assert ans == set() @@ -147,7 +233,7 @@ def test_reader_enumerate_fields(tmpdir): j = journal.Reader(path=tmpdir.strpath) with j: - with skip_enosys(): + with skip_oserror(errno.ENOSYS): ans = j.enumerate_fields() assert isinstance(ans, set) assert ans == set() @@ -155,16 +241,16 @@ def test_reader_has_runtime_files(tmpdir): j = journal.Reader(path=tmpdir.strpath) with j: - with skip_enosys(): + with skip_oserror(errno.ENOSYS): ans = j.has_runtime_files() - assert ans == False + assert ans is False def test_reader_has_persistent_files(tmpdir): j = journal.Reader(path=tmpdir.strpath) with j: - with skip_enosys(): + with skip_oserror(errno.ENOSYS): ans = j.has_runtime_files() - assert ans == False + assert ans is False def test_reader_converters(tmpdir): converters = {'xxx' : lambda arg: 'yyy'} @@ -200,3 +286,13 @@ long_ago = datetime.datetime(1970, 5, 4) j.seek_realtime(long_ago) + +def test_journal_stream(): + # This will fail when running in a bare chroot without /run/systemd/journal/stdout + with skip_oserror(errno.ENOENT): + stream = journal.stream('test_journal.py') + + res = stream.write('message...\n') + assert res in (11, None) # Python2 returns None + + print('printed message...', file=stream) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/systemd/test/test_login.py new/python-systemd-234/systemd/test/test_login.py --- old/python-systemd-233/systemd/test/test_login.py 1970-01-01 01:00:00.000000000 +0100 +++ new/python-systemd-234/systemd/test/test_login.py 2017-03-26 03:33:59.000000000 +0200 @@ -0,0 +1,48 @@ +from __future__ import print_function +import select +import contextlib +import errno + +from systemd import login + +import pytest + [email protected] +def skip_oserror(code): + try: + yield + except (OSError, IOError) as e: + if e.errno == code: + pytest.skip() + raise + +def test_seats(): + # just check that we get some sequence back + with skip_oserror(errno.ENOENT): + seats = login.seats() + assert len(seats) >= 0 + +def test_sessions(): + with skip_oserror(errno.ENOENT): + sessions = login.sessions() + assert len(sessions) >= 0 + +def test_machine_names(): + with skip_oserror(errno.ENOENT): + machine_names = login.machine_names() + assert len(machine_names) >= 0 + +def test_uids(): + with skip_oserror(errno.ENOENT): + uids = login.uids() + assert len(uids) >= 0 + +def test_monitor(): + p = select.poll() + + with skip_oserror(errno.ENOENT): + m = login.Monitor("machine") + p.register(m, m.get_events()) + login.machine_names() + p.poll(1) + login.machine_names() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/systemd/util.c new/python-systemd-234/systemd/util.c --- old/python-systemd-233/systemd/util.c 1970-01-01 01:00:00.000000000 +0100 +++ new/python-systemd-234/systemd/util.c 2017-03-26 03:33:59.000000000 +0200 @@ -0,0 +1,187 @@ +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +/* stuff imported from systemd without any changes */ + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <net/if.h> + +#include "util.h" + +int safe_atou(const char *s, unsigned *ret_u) { + char *x = NULL; + unsigned long l; + + assert(s); + assert(ret_u); + + /* strtoul() is happy to parse negative values, and silently + * converts them to unsigned values without generating an + * error. We want a clean error, hence let's look for the "-" + * prefix on our own, and generate an error. But let's do so + * only after strtoul() validated that the string is clean + * otherwise, so that we return EINVAL preferably over + * ERANGE. */ + + errno = 0; + l = strtoul(s, &x, 0); + if (errno > 0) + return -errno; + if (!x || x == s || *x) + return -EINVAL; + if (s[0] == '-') + return -ERANGE; + if ((unsigned long) (unsigned) l != l) + return -ERANGE; + + *ret_u = (unsigned) l; + return 0; +} + +static bool socket_ipv6_is_supported(void) { + if (access("/proc/net/if_inet6", F_OK) != 0) + return false; + + return true; +} + +static int assign_address(const char *s, + uint16_t port, + union sockaddr_union *addr, unsigned *addr_len) { + int r; + + /* IPv4 in w.x.y.z:p notation? */ + r = inet_pton(AF_INET, s, &addr->in.sin_addr); + if (r < 0) + return -errno; + + if (r > 0) { + /* Gotcha, it's a traditional IPv4 address */ + addr->in.sin_family = AF_INET; + addr->in.sin_port = htobe16(port); + *addr_len = sizeof(struct sockaddr_in); + } else { + unsigned idx; + + if (strlen(s) > IF_NAMESIZE-1) + return -EINVAL; + + /* Uh, our last resort, an interface name */ + idx = if_nametoindex(s); + if (idx == 0) + return -EINVAL; + + addr->in6.sin6_family = AF_INET6; + addr->in6.sin6_port = htobe16(port); + addr->in6.sin6_scope_id = idx; + addr->in6.sin6_addr = in6addr_any; + *addr_len = sizeof(struct sockaddr_in6); + } + + return 0; +} + + +int parse_sockaddr(const char *s, + union sockaddr_union *addr, unsigned *addr_len) { + + char *e, *n; + unsigned u; + int r; + + if (*s == '[') { + /* IPv6 in [x:.....:z]:p notation */ + + e = strchr(s+1, ']'); + if (!e) + return -EINVAL; + + n = strndupa(s+1, e-s-1); + + errno = 0; + if (inet_pton(AF_INET6, n, &addr->in6.sin6_addr) <= 0) + return errno > 0 ? -errno : -EINVAL; + + e++; + if (*e) { + if (*e != ':') + return -EINVAL; + + e++; + r = safe_atou(e, &u); + if (r < 0) + return r; + + if (u <= 0 || u > 0xFFFF) + return -EINVAL; + + addr->in6.sin6_port = htobe16((uint16_t)u); + } + + addr->in6.sin6_family = AF_INET6; + *addr_len = sizeof(struct sockaddr_in6); + + } else { + e = strchr(s, ':'); + if (e) { + r = safe_atou(e+1, &u); + if (r < 0) + return r; + + if (u <= 0 || u > 0xFFFF) + return -EINVAL; + + n = strndupa(s, e-s); + return assign_address(n, u, addr, addr_len); + + } else { + r = safe_atou(s, &u); + if (r < 0) + return assign_address(s, 0, addr, addr_len); + + /* Just a port */ + if (u <= 0 || u > 0xFFFF) + return -EINVAL; + + if (socket_ipv6_is_supported()) { + addr->in6.sin6_family = AF_INET6; + addr->in6.sin6_port = htobe16((uint16_t)u); + addr->in6.sin6_addr = in6addr_any; + *addr_len = sizeof(struct sockaddr_in6); + } else { + addr->in.sin_family = AF_INET; + addr->in.sin_port = htobe16((uint16_t)u); + addr->in.sin_addr.s_addr = INADDR_ANY; + *addr_len = sizeof(struct sockaddr_in); + } + } + } + + return 0; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/systemd/util.h new/python-systemd-234/systemd/util.h --- old/python-systemd-233/systemd/util.h 1970-01-01 01:00:00.000000000 +0100 +++ new/python-systemd-234/systemd/util.h 2017-03-26 03:33:59.000000000 +0200 @@ -0,0 +1,33 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <netinet/ip.h> +#include <arpa/inet.h> + +union sockaddr_union { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; +}; + +int safe_atou(const char *s, unsigned *ret_u); +int parse_sockaddr(const char *s, + union sockaddr_union *addr, unsigned *addr_len); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-systemd-233/update-constants.py new/python-systemd-234/update-constants.py --- old/python-systemd-233/update-constants.py 1970-01-01 01:00:00.000000000 +0100 +++ new/python-systemd-234/update-constants.py 2017-03-26 03:33:59.000000000 +0200 @@ -0,0 +1,9 @@ +import sys + +for file in sys.argv[1:]: + lines = iter(open(file).read().splitlines()) + for line in lines: + if line.startswith('#define SD_MESSAGE') and '_STR ' not in line: + if line.endswith('\\'): + line = line[:-1] + next(lines) + print(' '.join(line.split()))
