python - 有没有一种惯用的方法来使用 setuptools 安装 systemd 单元?
问题描述
我正在分发一个可以导入并用作库的模块。它还附带一个可执行文件——通过安装console_scripts
——供人们使用。
该可执行文件也可以作为 systemd 服务 ( Type=simple
) 启动,以向系统提供守护程序。
systemd 服务需要在其行中引用绝对路径ExecStart
,所以我需要弄清楚console_script
安装到哪里。
使用 CMake、autotools 或 Meson 等其他构建 systemd,我可以直接访问前缀,然后使用configure_file
(meson) 之类的东西替换@PREFIX@
,foo.service.in
然后将生成的单元安装到$prefix/lib/systemd/system/
.
我只是不知道如何使用 setuptools 来做到这一点。Inside setup.py
,sys.prefix
设置为python的 prefix,这不是一回事。我尝试过覆盖install_data
and install
,但是这些方法都有各种问题,例如在通过 构建轮子时损坏pip
,或者在卸载时留下文件。/usr
(当我们没有在系统范围内安装时,我可以不安装服务;如果前缀不是或者/usr/local
无论如何,systemd 将无法找到它。)
有人指给我看一个网站,上面说你不应该用 setuptools 做这个:
顺便提一下,数据文件的这种封装意味着您实际上不能将数据文件安装到用户机器上的任意位置。这是一个功能,而不是一个错误。
这听起来像我在这里反对谷物。我真的在寻找指针或例子来告诉我我应该在这里做什么。如果那是“不要使用 setuptools”,那很好 - 但是欢迎就首选的东西提出建议。
解决方案
我会说不要为此使用setuptools,这不是它的用途。而是使用目标发行版的包管理器(apt、rpm、flatpak、pacman、snap 等)。
我相信systemd和特定于操作系统(Linux 发行版、Linux init 系统)的东西超出了 Python 打包、pip、setuptools等的范围。尽可能合理地由setuptools负责,以便项目保持pip-installable,因此项目本身提供了访问systemd特定文件但不安装它们的简单方法(可能使用命令my-thing-generate-systemd-files --target path/to/output
例如,这将简化项目用户的任务)。另一方面,提供特定于 Linux 发行版的包(deb、rpm 等),如果我没记错的话,有一些工具允许从 Python 项目(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
- 等等
推荐阅读
- php - 如何通过 Laravel 中的 hasMany 关系过滤条目
- vb.net - 如何在 vb.net 的 word 文档中指定插入点?
- r - 替换列中的值
- c++ - 使用 VB 示例与 SerialCOM 进行 C++ 字符串 ASCII 通信
- kubernetes - GKE 节点意外删除并重新创建
- ruby-on-rails - 带有 RSpec 测试的 Capybara 上的 ActionController::InvalidAuthenticityToken
- c# - 如何使用 C# 从 SQL Server 表中获取一些 MAX 和 MIN 值
- python - 如何解决 KeyError:u“[Index([..], dtype='object')] 中没有 [列]”
- apache - Apache 使用 websocket 进行负载平衡
- forms - Karma 中的测试错误:无法绑定到“cdkObserveContentDisabled”,因为它不是“标签”的已知属性