有没有一种惯用的方法可以使用 setuptools 安装 systemd 单元?
Is there an idiomatic way to install systemd units with setuptools?
我正在分发一个可以导入并用作库的模块。它还附带一个可执行文件——通过 console_scripts
安装——供人们使用。
该可执行文件还可以作为系统服务 (Type=simple
) 启动,为系统提供守护进程。
systemd 服务需要在它们的 ExecStart
行中引用 绝对路径 ,所以我需要弄清楚 console_script
安装到哪里。
使用 CMake、autotools 或 Meson 等其他构建系统,我可以直接访问前缀,然后使用 configure_file
(介子)之类的东西替换 foo.service.in
中的 @PREFIX@
,并且然后将生成的单元安装到 $prefix/lib/systemd/system/
.
我只是想不出如何使用设置工具来做到这一点。在 setup.py
中,sys.prefix
设置为 python 的前缀 ,这不是一回事。我尝试过覆盖 install_data
和 install
,但这些方法都有各种问题,例如在通过 pip
构建轮子时损坏,或者在卸载时留下文件。 (当我们没有在系统范围内安装时,我可以不安装服务;如果前缀不是 /usr
或 /usr/local
,systemd 将无法找到它。)
有人指点我at a website which says that you're not supposed to do this with setuptools:
Note, by the way, that this encapsulation of data files means that you can't actually install data files to some arbitrary location on a user's machine; this is a feature, not a bug.
这听起来好像我只是违背了这里的原则。我真的在寻找指示或示例来告诉我我应该在这里做什么。如果那是 "don't use setuptools",很好 - 但欢迎就首选的东西提出建议。
我会说不要为此使用 setuptools,这不是它的用途。而是使用目标发行版的包管理器(apt、rpm、flatpak、pacman、snap 等)。
我相信 systemd 以及特定于操作系统的东西(Linux 发行版,Linux init system) 超出了 Python 打包、pip、setuptools 等的范围。尽可能合理地保留在 setuptools 的职责,以便项目保持 pip-installable,并且项目本身提供了访问 [=24= 的简单方法]systemd 特定文件但不安装它们(例如,可能使用命令 my-thing-generate-systemd-files --target path/to/output
,这将简化项目用户的任务)。另一方面,提供 Linux-特定于发行版的包(deb、rpm 等),如果我没记错的话,有一些工具可以从 Python 项目开始构建此类包(a sdist 或源代码库)。
一些想法(未经测试的快速搜索,不是推荐):
- https://pypi.org/project/pyp2rpm/(来自 Fedora)
- https://src.fedoraproject.org/rpms/pyproject-rpm-macros(来自 Fedora)
- https://pypi.org/project/stdeb/(未维护?)
- https://pypi.org/project/py2deb/(未维护?)
- https://snapcraft.io/docs/python-apps(来自 Ubuntu,新标准?)
- https://fpm.readthedocs.io/
- https://briefcase.readthedocs.io/en/stable/reference/platforms/linux/appimage.html
- 等等
我正在分发一个可以导入并用作库的模块。它还附带一个可执行文件——通过 console_scripts
安装——供人们使用。
该可执行文件还可以作为系统服务 (Type=simple
) 启动,为系统提供守护进程。
systemd 服务需要在它们的 ExecStart
行中引用 绝对路径 ,所以我需要弄清楚 console_script
安装到哪里。
使用 CMake、autotools 或 Meson 等其他构建系统,我可以直接访问前缀,然后使用 configure_file
(介子)之类的东西替换 foo.service.in
中的 @PREFIX@
,并且然后将生成的单元安装到 $prefix/lib/systemd/system/
.
我只是想不出如何使用设置工具来做到这一点。在 setup.py
中,sys.prefix
设置为 python 的前缀 ,这不是一回事。我尝试过覆盖 install_data
和 install
,但这些方法都有各种问题,例如在通过 pip
构建轮子时损坏,或者在卸载时留下文件。 (当我们没有在系统范围内安装时,我可以不安装服务;如果前缀不是 /usr
或 /usr/local
,systemd 将无法找到它。)
有人指点我at a website which says that you're not supposed to do this with setuptools:
Note, by the way, that this encapsulation of data files means that you can't actually install data files to some arbitrary location on a user's machine; this is a feature, not a bug.
这听起来好像我只是违背了这里的原则。我真的在寻找指示或示例来告诉我我应该在这里做什么。如果那是 "don't use setuptools",很好 - 但欢迎就首选的东西提出建议。
我会说不要为此使用 setuptools,这不是它的用途。而是使用目标发行版的包管理器(apt、rpm、flatpak、pacman、snap 等)。
我相信 systemd 以及特定于操作系统的东西(Linux 发行版,Linux init system) 超出了 Python 打包、pip、setuptools 等的范围。尽可能合理地保留在 setuptools 的职责,以便项目保持 pip-installable,并且项目本身提供了访问 [=24= 的简单方法]systemd 特定文件但不安装它们(例如,可能使用命令 my-thing-generate-systemd-files --target path/to/output
,这将简化项目用户的任务)。另一方面,提供 Linux-特定于发行版的包(deb、rpm 等),如果我没记错的话,有一些工具可以从 Python 项目开始构建此类包(a sdist 或源代码库)。
一些想法(未经测试的快速搜索,不是推荐):
- https://pypi.org/project/pyp2rpm/(来自 Fedora)
- https://src.fedoraproject.org/rpms/pyproject-rpm-macros(来自 Fedora)
- https://pypi.org/project/stdeb/(未维护?)
- https://pypi.org/project/py2deb/(未维护?)
- https://snapcraft.io/docs/python-apps(来自 Ubuntu,新标准?)
- https://fpm.readthedocs.io/
- https://briefcase.readthedocs.io/en/stable/reference/platforms/linux/appimage.html
- 等等