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

Avoid system calls to interact with systemd services #2680

Open
FroggyFlox opened this issue Sep 23, 2023 · 5 comments
Open

Avoid system calls to interact with systemd services #2680

FroggyFlox opened this issue Sep 23, 2023 · 5 comments

Comments

@FroggyFlox
Copy link
Member

We currently use a lot of system calls via run_command() (a wrapper around subprocess.Popen()) to interact with various systemd units. See system.services.py for a very good list of examples. This is very cumbersome to operate, heavy to parse the outputs, and most likely rather wasteful.

A better approach would most likely be to directly interact with systemd DBus. While we already have the dbus library as a dependency for interacting with the SSSD DBus responder InfoPipe, there is a python library to simplify interacting with systemd units and services: pystemd

GitHub: https://github.com/systemd/pystemd
Their description seems to fit our needs exactly:

This library allows you to talk to systemd over dbus from python, without actually thinking that you are talking to systemd over dbus. This allows you to programmatically start/stop/restart/kill and verify services status from systemd point of view, avoiding executing subprocess.Popen(['systemctl', ... and then parsing the output to know the result.

The project is hosted by the systemd organization on Github, and seems actively maintained (https://github.com/systemd/pystemd/releases). It is also easily available on PyPI.org, making it easy to be added to our pyproject.toml.

It is licensed LGPL-2.1: https://github.com/systemd/pystemd/blob/main/LICENSE
It is currently supporting Python3.6 and later.
Note that to build it, we would need to following new system package: systemd-devel.

An example use on how to restart a service is described at systemd/pystemd#60 (comment)

It would allow us to access all properties and methods described at https://www.freedesktop.org/software/systemd/man/org.freedesktop.systemd1.html#Properties1

@Hooverdan96
Copy link
Member

Hooverdan96 commented Sep 23, 2023

This looks interesting and seems to allow for simplification from constructing the commands for systemd to a simpler way!
The example you posted up there, and the question posed therein about sudo would not apply to Rockstor, since we are running these things with root in general anyway?

Would this come before or after below design decision?

#2650 (Replace supervisord with further systemd intergration)

In my mind this would probably come before further moving items into the systemd realm, so the transition would be simpler, too. Or am I connecting two things that are really independent?

@FroggyFlox
Copy link
Member Author

The example you posted up there, and the question posed therein about sudo would not apply to Rockstor, since we are running these things with root in general anyway?

That's something we'll have to verify, indeed. I'm thinking the same as you so far. I have only briefly tried with restarting the rockstor service that way and it was fine. It would need testing with a service such as sshd, I suppose.

Would this come before or after below design decision?

#2650 (Replace supervisord with further systemd intergration)

In my mind this would probably come before further moving items into the systemd realm, so the transition would be simpler, too. Or am I connecting two things that are really independent?

Very good point. My first thought is that it shouldn't really matter as I'm hoping we can "simply" change our current wrappers around systemctl calls to use pystemd instead while still providing the same returns. During the work on #2650, I'm hoping the calls to our wrappers around supervisorctl can be swapped to our wrappers around systemctl. We'll have to keep an eye out for that indeed, though.

@FroggyFlox
Copy link
Member Author

As mentioned in #2768 (comment), installing pystemd carries a few requirements: it currently fails with:

buildvm:/opt/rockstor # poetry add pystemd
Using version ^0.13.2 for pystemd

Updating dependencies
Resolving dependencies... (0.2s)

Package operations: 2 installs, 0 updates, 0 removals

  • Installing lxml (5.3.0)
  • Installing pystemd (0.13.2): Failed

  ChefBuildError

  Backend subprocess exited when trying to invoke get_requires_for_build_wheel
  
  Package libsystemd was not found in the pkg-config search path.
  Perhaps you should add the directory containing `libsystemd.pc'
  to the PKG_CONFIG_PATH environment variable
  No package 'libsystemd' found
  `pkg-config --modversion libsystemd` failed. Please ensure all prerequisite packages from README.md are installed.
  

  at /opt/pipx/venvs/poetry/lib64/python3.11/site-packages/poetry/installation/chef.py:164 in _prepare
      160│ 
      161│                 error = ChefBuildError("\n\n".join(message_parts))
      162│ 
      163│             if error is not None:
    → 164│                 raise error from None
      165│ 
      166│             return path
      167│ 
      168│     def _prepare_sdist(self, archive: Path, destination: Path | None = None) -> Path:

Note: This error originates from the build backend, and is likely not a problem with poetry but with pystemd (0.13.2) not supporting PEP 517 builds. You can verify this by running 'pip wheel --no-cache-dir --use-pep517 "pystemd (==0.13.2)"'.
buildvm:/opt/rockstor # poetry run pip wheel --no-cache-dir --use-pep517 "pystemd (==0.13.2)"
Collecting pystemd==0.13.2
  Downloading pystemd-0.13.2.tar.gz (308 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  error: subprocess-exited-with-error
  
  × Getting requirements to build wheel did not run successfully.
  │ exit code: 1
  ╰─> [5 lines of output]
      Package libsystemd was not found in the pkg-config search path.
      Perhaps you should add the directory containing `libsystemd.pc'
      to the PKG_CONFIG_PATH environment variable
      No package 'libsystemd' found
      `pkg-config --modversion libsystemd` failed. Please ensure all prerequisite packages from README.md are installed.
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.

note: This error originates from a subprocess, and is likely not a problem with pip.

This is in line with pystemd's "build from source" instructions:
https://github.com/systemd/pystemd?tab=readme-ov-file#build--from-source

@phillxnet
Copy link
Member

@FroggyFlox Re:

Package libsystemd was not found in the pkg-config search path.

Is this not just a system (Leap) package that we require to be installed?

@FroggyFlox
Copy link
Member Author

Absolutely. I forgot that I had already tried and tested pystemd before opening this issue so it turns out I already had described that in my original post; I just completely forgot about it... Sorry. See below:

Note that to build it, we would need to following new system package: systemd-devel.

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

3 participants