Search code examples
python-3.xsystemddbusntp

How to use pystemd to control systemd timedated ntp service?


I'm working on a python app that needs to get the NTPSynchronized parameter from system-timedated. I'd also like to be able to start and stop the NTP service by using the SetNTP method.

To communicate with timedated over d-bus I have been using this as reference: https://www.freedesktop.org/wiki/Software/systemd/timedated/

I previously got this working with dbus-python, but have since learned that this library has been deprecated. I tried the dbus_next package, but that does not have support for Python 3.5, which I need.

I came across the pystemd package, but I am unsure if this can be used to do what I want. The only documentation I have been able to find is this example (https://github.com/facebookincubator/pystemd), but I can not figure out how to use this to work with system-timedated.

Here is the code I have that works with dbus-python:

import dbus

BUS_NAME = 'org.freedesktop.timedate1`
IFACE = 'org.freedesktop.timedate1`

bus = dbus.SystemBus()
timedate_obj = bus.get_object(BUS_NAME, '/org/freedesktop/timedate1')

# Get synchronization value
is_sync = timedate_obj.Get(BUS_NAME, 'NTPSynchronized', dbus_interface=dbus.PROPERTIES_IFACE)

# Turn off NTP
timedate_obj.SetNTP(False,False, dbus_interface=IFACE)

Here's what I have so far with pystemd, but I don't think I'm accessing it in the right way:

from pystemd.systemd1 import Unit

unit = Unit(b'systemd-timesyncd.service')
unit.load()

# Try to access properties
prop = unit.Properties
prop.NTPSynchronized

Running that I get:

Attribute Error: 'SDInterface' object has no attribute 'NTPSynchronized'

I have a feeling that either the service I entered is wrong, or the way I'm accessing properties is wrong, or even both are wrong.

Any help or advice is appreciated.


Solution

  • Looking at the source code, it appears that using the pystemd.systemd1 Unit object has a default destination of "org.freedesktop.systemd1" + the service name (https://github.com/facebookincubator/pystemd/blob/master/pystemd/systemd1/unit.py)

    This is not what I want because I am trying to access "org.freedesktop.timedate1" So instead I instantiated it's base class SDObject from pystemd.base (https://github.com/facebookincubator/pystemd/blob/master/pystemd/base.py)

    The following code allowed me to get the sync status of NTP

    from pystemd.base import SDObject
    
    obj = SDObject(
        destination=b'org.freedesktop.timedate1',
        path=b'/org/freedesktop/timedate1',
        bus=None,
        _autoload=False
    )
    
    obj.load()
    
    is_sync = obj.Properties.Get('org.freedesktop.timedate1','NTPSynchronized')
    
    print(is_sync)
    

    Not sure if this is what the library author intended, but hey it works!