systemd/pystemd

Psystemd not working properly with PyInstaller

Opened this issue · 2 comments

In my project I needed a way to handle systemctl signals gracefully so I decided to use psystemd. Other alternatives did not perform properly. My main goal is to convert my Python script to executable and make it run as a service in the backgorund. The main problem I am facing rn is that my code cannot process systemctl stop signal gracefully. The way I implemented psystemd is given below.

from pystemd.systemd1 import Unit

if __name__ == "__main__":
    try:
        myc = Dlp_Service()
        myc.start()
        while True:
            sleep(1)

            if myc.unit.Unit.ActiveState == b"deactivating":
                myc.stop()
    except Exception as e:
        print(e)
        myc.stop()

It is initiated inside the Dlp_Service constructor like self.unit = Unit(b"myservice.service").
The error message is "ModuleNotFoundError: No module named 'pystemd.dbusexc'". The executable is created inside a virtual environment that has psystemd installed and this program works flawless as a Python script. How can i handle this error and use my program as executable?

I'm having the same issue. Here is my code:

from dataclasses import dataclass, field
from typing import List
from src.hardshell.checks.base import BaseCheck
from pystemd.systemd1 import Manager, Unit


@dataclass
class ServiceCheck(BaseCheck):
    path: str = None
    path_exists: bool = False
    permissions: List[int] = field(default_factory=list)
    recursive: bool = False

    def run_check(self, current_os, global_config):
        print("Running service check")
        manager = Manager()
        manager.load()
        result = manager.Manager.ListUnitFiles()
        print(result)

I'm getting this error:

Traceback (most recent call last):
  File "hardshell/main.py", line 6, in <module>
  File "PyInstaller/loader/pyimod02_importers.py", line 419, in exec_module
  File "hardshell/scan.py", line 4, in <module>
  File "PyInstaller/loader/pyimod02_importers.py", line 419, in exec_module
  File "hardshell/common/checks.py", line 7, in <module>
  File "PyInstaller/loader/pyimod02_importers.py", line 419, in exec_module
  File "hardshell/checks/linux/service.py", line 5, in <module>
  File "PyInstaller/loader/pyimod02_importers.py", line 419, in exec_module
  File "pystemd/__init__.py", line 102, in <module>
  File "PyInstaller/loader/pyimod02_importers.py", line 419, in exec_module
  File "pystemd/DBus/__init__.py", line 9, in <module>
  File "PyInstaller/loader/pyimod02_importers.py", line 419, in exec_module
  File "pystemd/base.py", line 14, in <module>
  File "pystemd/dbuslib.pyx", line 16, in init pystemd.dbuslib
ModuleNotFoundError: No module named 'pystemd.dbusexc'
[243559] Failed to execute script 'main' due to unhandled exception!

I'm getting the same error whether I run the executable with sudo -E dist/main/main or dist/main/main.

The script works fine in my poetry package.

This is the pyinstaller output when it is ran with poetry run pyinstaller src/hardshell/main.py

81 INFO: PyInstaller: 6.8.0, contrib hooks: 2024.7
81 INFO: Python: 3.10.12
82 INFO: Platform: Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.35
82 INFO: Python environment: /home/tom/.cache/pypoetry/virtualenvs/hardshell-0zkgacHU-py3.10
86 INFO: wrote /mnt/c/repos/tom/hardshell/main.spec
169 INFO: Module search paths (PYTHONPATH):
['/usr/lib/python310.zip',
 '/usr/lib/python3.10',
 '/usr/lib/python3.10/lib-dynload',
 '/home/tom/.cache/pypoetry/virtualenvs/hardshell-0zkgacHU-py3.10/lib/python3.10/site-packages',
 '/mnt/c/repos/tom/hardshell/src',
 '/mnt/c/repos/tom/hardshell']
235 INFO: checking Analysis
293 INFO: checking PYZ
352 INFO: checking PKG
362 INFO: Building because python_lib_name changed
362 INFO: Building PKG (CArchive) main.pkg
401 INFO: Building PKG (CArchive) main.pkg completed successfully.
404 INFO: Bootloader /home/tom/.cache/pypoetry/virtualenvs/hardshell-0zkgacHU-py3.10/lib/python3.10/site-packages/PyInstaller/bootloader/Linux-64bit-intel/run
404 INFO: checking EXE
408 INFO: Building because python_lib changed
408 INFO: Building EXE from EXE-00.toc
412 INFO: Copying bootloader EXE to /mnt/c/repos/tom/hardshell/build/main/main
417 INFO: Appending PKG archive to custom ELF section in EXE
500 INFO: Building EXE from EXE-00.toc completed successfully.
504 INFO: checking COLLECT
508 INFO: Building COLLECT COLLECT-00.toc
1312 INFO: Building COLLECT COLLECT-00.toc completed successfully.

I have to wonder if pyinstaller isn't picking up all of the dependencies. Thoughts?

I was able to fix the issue by adding these to my spec file:

    hiddenimports=[
        "pystemd.base",
        "pystemd.dbusexc",
        "pystemd.dbuslib",
    ],