Reputation: 103
I'm trying to start a dbus timer from python.
At the moment I was able to launch it through this script:
import dbus
from subprocess import call
def scheduleWall( time, message ):
call(['systemd-run --on-active='+str(time) +' --unit=scheduled-message --description="'+ message +'" wall "'+ message +'"'], shell=True)
I'd like to not use "call", but try to use "StartTransientUnit", but I wasn't able to understand the format of the call at all! I'm rather new to dbus and python.
def scheduleWall( time, message ):
try:
bus = dbus.SystemBus()
systemd1 = bus.get_object("org.freedesktop.systemd1"," /org/freedesktop/systemd1")
manager = dbus.Interface(systemd1, 'org.freedesktop.systemd1.Manager')
obj = manager.StartTransientUnit('scheduled-message.timer','fail',[????],[????])
except:
pass
Is startTransientUnit the right method to call? how should I call it?
Upvotes: 1
Views: 1233
Reputation: 2742
TL;DR: stick to systemd-run
:)
I don’t think StartTransientUnit
is quite the right method – you need to create two transient units, after all: the timer unit, and the service unit that it will start (which will run wall
later). Perhaps you can use StartTransientUnit
for the timer, but at least not for the service. You also need to set all the properties that the two units need (OnActiveSec=
for the timer, ExecStart=
for the service, probably some more…) – you can see how systemd-run
does it by running busctl monitor org.freedesktop.systemd1
and then doing systemctl run --on-active 1s /bin/true
in another terminal. (The main calls seem to be UnitNew
and JobNew
.)
I’ll admit, to me this seems rather complicated, and if systemd-run
already exists to do the job for you, why not use it? The only change I would make is to eliminate the shell part and pass an array of arguments instead of a single space-separated string, with something like this (untested):
subprocess.run(['systemd-run', '--on-active', str(time), ' --unit', 'scheduled-message', '--description', message, 'wall', message)
Upvotes: 1