Checking NTP state with Python/dbus

Continuing the discussion from Check NTP synchronization status from Python:

I’m getting an error trying to replicate this code. When I attempt to call the GetAll method, I receive this error:
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.ServiceUnknown: The name :1.1121 was not provided by any .service files

I don’t think this error is due to the way the container is setup because I’m able to communicate to systemd via DBus.

Does this have anything to do with the switch from systemd-timesyncd to chrony? I’d like to stick with Python to get the current state of NTP on the system, but if this method is no longer valid would parsing the output from a chronyc command suffice?

Thanks!

Hi,
Just make sure we are on the same page, are you running this code?:

import python
bus = dbus.SystemBus()
proxy = bus.get_object('org.freedesktop.timedate1',
                       '/org/freedesktop/timedate1')
interface = dbus.Interface(proxy, 'org.freedesktop.DBus.Properties')
properties = interface.GetAll('org.freedesktop.timedate1')
print(properties)

Kind regards,
Theodor

Yep, sorry I should have included that with my question. The code block fails at interface.GetAll("org.freedesktop.timedate1") with this exception:

dbus.exceptions.DBusException: org.freedesktop.DBus.Error.ServiceUnknown: The name :1.1121 was not provided by any .service files

I tried to reproduce the problem, but it works correctly for me. What I did is I took a python base image, installed python3-dbus, ran “export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket”, and ran the code you mentioned, and I could see the expected output. What version of python did you try it on?

I ran it using v3.6.8. I’m wondering if it is a problem with the way the image is setup? I have an ENV line to set the system bus address, but I’m wondering if the way I installed dbus-python package is bad. I didn’t use the Debian package, I just used pip and my requirements file. Let me try with your method, thanks!

Indeed, having that ENV line in the Dockerfile might not work, depending on how your container starts systemd. If you’re using an old resin/ base image, you might actually be making the container’s systemd init use that socket, which can cause all sorts of problems. So in general we recommend setting the env var only for the processes that need it. And it might look like everything’s okay because you can reach systemd over DBus, but you want to make sure you can reach the host’s systemd, and not the container’s.

(I think installing the package with pip is probably fine though)

Thanks for the help!

Here’s my Dockerfile for this container:
FROM balenalib/raspberrypi3-python:3.6-build

WORKDIR /src

ENV INITSYSTEM on
ENV DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

RUN apt-get update && apt-get install -y \
    vim \
    && rm -rf /var/lib/apt/lists/*

COPY ./requirements.txt /src/requirements.txt
RUN pip3 install -r /src/requirements.txt
COPY . /src/

# Add path of common container package
ENV PYTHONPATH="$PYTHONPATH:/var/lib/common_package"

CMD ["python", "monitor.py"]

I think specifically installing the python3-dbus package fixed the problem I was encountering. I’m able to use the DBus calls through Python now. Thanks for the help!

That’s good to hear!