Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Psystemd not working properly with PyInstaller #90

Open
MuhammedAliISIK opened this issue Oct 24, 2023 · 2 comments
Open

Psystemd not working properly with PyInstaller #90

MuhammedAliISIK opened this issue Oct 24, 2023 · 2 comments

Comments

@MuhammedAliISIK
Copy link

MuhammedAliISIK commented Oct 24, 2023

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?

@tomburge
Copy link

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?

@tomburge
Copy link

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants