activando e desactivando um serviço de sistema em Python usando o DBus
O próximo picockpit-cliente reage a eventos de exclusão do frontend desactivando o seu serviço (a aplicação permanecerá instalada, no entanto).
Da mesma forma, quando decidir executar novamente a ligação picockpit-cliente, o serviço será reactivado e iniciado automaticamente para si.
Isto é possível usando o Interface Python DBus.
o DBus é um sistema de barramento para interagir com outras aplicações. As aplicações & serviços de sistema publicam uma certa interface sobre o DBus, que você pode usar.
Aqui está como fazer isso:
desactivar um serviço:
autocarro de importação
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'], Falso)manager.Reload()
Nós abrimos o SystemBus - há também um SessionBus ( dbus.SessionBus() ) que é usado para interagir com uma sessão do usuário. Neste caso queremos aceder aos serviços do Sistema, no entanto.
até gerir estas são chamadas "standard" - para aceder ao sistema é necessário passar por elas.
a próxima linha é onde instruímos o gerente a DesabilitarUnitFiles. Aqui estão mais algumas notas sobre isso:
- a primeira variável é um array de strings - mesmo que você queira desativar apenas um serviço, você o passa como um array.
- você passa em nome do seu serviço incluindo a parte '.service' - por exemplo picockpit-client.service
- a segunda variável é necessária e seria Falsa para desativar para cada boot (e Verdadeiro para desativar apenas para este tempo de execução)
Aqui está a assinatura para DisableUnitFiles de a documentação oficial do DBus / systemd / Freedesktop.org:
Note que é importante fornecer todas as variáveis ao interagir com a interface DBus! Eles são não opcional e "definido para padrões sãos", como você pode ser usado a partir de muitas outras interfaces / APIs.
Finalmente, li online que as mudanças precisam de ser cometidas usando manager.Reload() (a documentação diz: Reload() pode ser invocado para recarregar todos os arquivos de unidade)
habilitar e iniciar um serviço:
autocarro de importação
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'], Falso, Verdadeiro)
manager.Reload()
trabalho = gerente.RestartUnit('picockpit-client.service', 'fail')
Similar ao anterior, com a seguinte diferença para EnableUnitFiles:
- há duas variáveis booleanas após o array de strings que precisam ser passadas em
- a primeira variável booleana, como acima, determina se o serviço deve ser habilitado apenas para este tempo de execução (True) ou geralmente (False);
- a segunda variável booleana é, de certa forma, descrita de forma críptica: "A segunda controla se as ligações simbólicas que apontam para outras unidades devem ser substituídas, se necessário." Eu decidi defini-la como True.
Aqui está a assinatura da EnableUnitFiles a partir da documentação:
Olhando para ele, minha escolha de "Verdadeiro" pode possivelmente não ser sensata para outras aplicações ("força" implica uma espécie de sobreposição de segurança).
Finalmente, RestartUnit para realmente começar o serviço:
- note que isto requer um valor de string, não um conjunto de strings
- o segundo valor é uma string que especifica o modo. Por favor, consulte a página documentação oficial para os diferentes modos que são possíveis.
Aqui está a assinatura da RestartUnit:
Nota: Eu não lido com os valores de retorno, idealmente e especialmente para aplicações críticas, você gostaria de olhar para isso - consulte o documentação oficial.
Erros
Descoordenação de assinaturas
ERRO:dbus.connection:Incapaz de definir argumentos (['picockpit-client.service'],) de acordo com a assinatura 'asb': : Mais itens encontrados na assinatura D-Bus do que nos argumentos Python
Se você receber um erro como o acima, verifique se você está passando todos os parâmetros, conforme exigido pela assinatura na documentação.
Neste caso, eu tinha (errado):
manager.DisableUnitFiles(['picockpit-client.service'])
em vez do correcto:
manager.DisableUnitFiles(['picockpit-client.service'], Falso)
Certifique-se também de verificar se você está passando em um fio (s), onde um conjunto de cordas (como) é necessário.
Ref
- https://dbus.freedesktop.org/doc/dbus-python/tutorial.html
- https://www.freedesktop.org/wiki/Software/systemd/dbus/ <a documentação / API para Dbus / systemd