3

How to efficiently and correctly manage processes with python. I want to run commands like:

/etc/init.d/daemon stop
service daemon start
systemctl restart daemon

Is there any python module available for this?

Any help will be highly appreciated.

Arindam Choudhury
  • 2,816
  • 2
  • 18
  • 22
  • do you mean `subprocess` module or something like `supervisord`? Also, you can implement daemons in pure Python e.g., [Python daemon and systemd service](http://stackoverflow.com/a/30189540/4279) – jfs Aug 06 '15 at 22:40
  • Hi, I am looking for something like this: http://code.activestate.com/recipes/115875-controlling-windows-services/ , but for linux. – Arindam Choudhury Aug 10 '15 at 08:08
  • the simplest solution would be to run the corresponding commands (such as `systemctl restart `) using `subprocess` module though there could be corresponding Python wrappers. – jfs Aug 10 '15 at 17:39
  • Using subprocess doesn't handle systemctl's stdout/stderr. I routinely can't control what it prints during execution. Arindam's answer is what I was looking for. – dubmojo Sep 17 '19 at 19:37

1 Answers1

4

I found a way using systemd dbus interface. Here is the code:

import dbus
import subprocess
import os
import sys
import time

SYSTEMD_BUSNAME = 'org.freedesktop.systemd1'
SYSTEMD_PATH = '/org/freedesktop/systemd1'
SYSTEMD_MANAGER_INTERFACE = 'org.freedesktop.systemd1.Manager'
SYSTEMD_UNIT_INTERFACE = 'org.freedesktop.systemd1.Unit'

bus = dbus.SystemBus()

proxy = bus.get_object('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority')
authority = dbus.Interface(proxy, dbus_interface='org.freedesktop.PolicyKit1.Authority')
system_bus_name = bus.get_unique_name()

subject = ('system-bus-name', {'name' : system_bus_name})
action_id = 'org.freedesktop.systemd1.manage-units'
details = {}
flags = 1            # AllowUserInteraction flag
cancellation_id = '' # No cancellation id

result = authority.CheckAuthorization(subject, action_id, details, flags, cancellation_id)

if result[1] != 0:
    sys.exit("Need administrative privilege")

systemd_object = bus.get_object(SYSTEMD_BUSNAME, SYSTEMD_PATH)
systemd_manager = dbus.Interface(systemd_object, SYSTEMD_MANAGER_INTERFACE)

unit = systemd_manager.GetUnit('cups.service')
unit_object = bus.get_object(SYSTEMD_BUSNAME, unit)
#unit_interface = dbus.Interface(unit_object, SYSTEMD_UNIT_INTERFACE)

#unit_interface.Stop('replace')
systemd_manager.StartUnit('cups.service', 'replace')

while list(systemd_manager.ListJobs()):
    time.sleep(2)
    print 'there are pending jobs, lets wait for them to finish.'

prop_unit = dbus.Interface(unit_object, 'org.freedesktop.DBus.Properties')

active_state = prop_unit.Get('org.freedesktop.systemd1.Unit', 'ActiveState')

sub_state = prop_unit.Get('org.freedesktop.systemd1.Unit', 'SubState')

print active_state, sub_state
Arindam Choudhury
  • 2,816
  • 2
  • 18
  • 22
  • 1
    The authentication bit is still a mystery to me, but it works! – dubmojo Sep 17 '19 at 19:36
  • 1
    This works perfectly! For my case, I wanted to manage services on a web interface like Django/Flask, so the authentication gave me hiccups at first, but I managed to tackle is by using this [solution on AskUbuntu](https://askubuntu.com/a/1251563/726285). Hope it'll help someone! Thanks Arindam! – Redgren Grumbholdt Dec 25 '20 at 09:10