in- en uitschakelen van een systemd service in Python met behulp van DBus
De komende picockpit-client reageert op verwijderingsgebeurtenissen van de frontend door de dienst uit te schakelen (de applicatie blijft echter wel geïnstalleerd).
Op dezelfde manier, wanneer je beslist om picockpit-client connect opnieuw uit te voeren, zal de dienst automatisch opnieuw ingeschakeld en gestart worden voor jou.
Dit is mogelijk door gebruik te maken van de Python DBus interface.
de DBus is een bussysteem voor interactie met andere toepassingen. De applicaties en systeemdiensten publiceren een bepaalde interface over de DBus, die u kunt gebruiken.
Hier is hoe je het moet doen:
een dienst uitschakelen:
importeren dbus
system_bus = dbus.SystemBus()
systemd1 = system_bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1')
manager = dbus.Interface(systemd1, "org.freedesktop.systemd1.Manager")
manager.DisableUnitFiles(['picockpit-client.service'], False)manager.Reload()
We openen de SystemBus - is er ook een SessionBus ( dbus.SessionBus() ) die gebruikt wordt om te interageren met een gebruikerssessie. In dit geval willen we echter toegang tot systeemservices.
tot aan manager zijn dit "standaard" aanroepen - om toegang te krijgen tot systemd moet je er doorheen.
de volgende regel is waar we de manager instrueren om UnitFiles uit te schakelen. Hier zijn wat meer notities over dat:
- de eerste variabele is een array van strings - zelfs als je maar één dienst wilt uitschakelen, geef je die door als een array.
- geef je de naam van je service op, inclusief het '.service' gedeelte - bijv. picockpit-client.service
- de tweede variabele is vereist en zou False zijn om uit te schakelen bij elke boot (en True om alleen voor deze runtime uit te schakelen)
Hier is de handtekening voor DisableUnitFiles van de officiële DBus / systemd / Freedesktop.org documentatie:
Let op, het is belangrijk om alle variabelen mee te geven bij interactie met de DBus interface! Ze zijn niet optioneel en "set to sane defaults", zoals u gewend bent van veel andere interfaces / API's.
Tenslotte heb ik online gelezen dat de wijzigingen moeten worden vastgelegd door gebruik te maken van manager.Reload() (de documentatie zegt: Reload() kan worden aangeroepen om alle eenheidsbestanden opnieuw te laden)
een dienst inschakelen en starten:
importeren dbus
system_bus = dbus.SystemBus()
systemd1 = system_bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1')
manager = dbus.Interface(systemd1, "org.freedesktop.systemd1.Manager")
manager.EnableUnitFiles(['picockpit-client.service'], False, True)
manager.Reload()
job = manager.RestartUnit('picockpit-client.service', 'fail')
Vergelijkbaar met het bovenstaande, met het volgende verschil voor EnableUnitFiles:
- er zijn twee booleaanse variabelen na de array van strings die NODIG moeten worden doorgegeven
- de eerste booleaanse variabele, zoals hierboven, bepaalt of de dienst moet worden ingeschakeld voor alleen deze runtime (True) of in het algemeen (False);
- de tweede booleaanse variabele wordt, enigszins cryptisch, beschreven als: "De tweede regelt of symlinks die naar andere eenheden wijzen, zo nodig worden vervangen." Ik heb besloten om deze op True te zetten.
Hier is de EnableUnitFiles handtekening uit de documentatie:
Mijn keuze voor "True" is misschien niet verstandig voor andere toepassingen ("force" impliceert een soort opheffing van de veiligheid).
Eindelijk, HerstartUnit om de dienst daadwerkelijk te starten:
- Merk op dat dit een string waarde neemt, niet een array van strings
- de tweede waarde is een string die de modus specificeert. Raadpleeg de officiële documentatie voor de verschillende modi die mogelijk zijn.
Hier is de RestartUnit handtekening:
Opmerking: Ik behandel de terugkeerwaarden niet, idealiter en vooral voor kritieke toepassingen, zou u dat willen bekijken - raadpleeg de officiële documentatie.
Fouten
Handtekening mismatch
ERROR:dbus.connection:Onmogelijk om argumenten (['picockpit-client.service'],) in te stellen volgens signatuur 'asb': : Meer items gevonden in D-Bus handtekening dan in Python argumenten
Als je een fout krijgt zoals hierboven, controleer dan of je alle parameters doorgeeft zoals vereist door de handtekening in de documentatie.
In dit geval had ik het (mis):
manager.DisableUnitFiles(['picockpit-client.service'])
in plaats van de juiste:
manager.DisableUnitFiles(['picockpit-client.service'], False)
Zorg er ook voor dat je controleert of je een string (s), waarbij een array van strings (als) is vereist.
Ref
- https://dbus.freedesktop.org/doc/dbus-python/tutorial.html
- https://www.freedesktop.org/wiki/Software/systemd/dbus/ <-de documentatie / API voor Dbus / systemd