编译时配置

编译时配置

我想发布一个应用程序,只需注册为systemd服务即可。

除了应用程序之外,我还想提供一个脚本来将应用程序注册为systemd服务。

因此,目前,我使用模板文件和复制并更新其值的myapp.service脚本来发布应用程序。myapp.service

但我不喜欢这个解决方案。

我可以.service从命令行创建文件吗?就像是systemd new -name myapp -description "my description" -after network.target -exec path/to/exec

答案1

有两种基本方法。

编译时配置

这是许多软件打包商所采取的方法。

一种是使用宏。在包生成时,某种形式的宏预处理器在宏化服务单元文件上运行,并带有表示配置的参数。然后将输出放入包中,这是一个定制的服务单元文件。

systemd 本身就是一个例子。这kmod-static-nodes.service.in文件包含宏:

ExecStart=@KMOD@ static-nodes --format=tmpfiles --output=/run/tmpfiles.d/static-nodes.conf

构建 systemd(名为“Meson”)的大量 Python 脚本除了许多其他内容之外还包含基于正则表达式的宏预处理器。该预处理器在 上运行kmod-static-nodes.service.in,替换KMOD宏以生成kmod-static-nodes.service进入包的 。替换是一个字符串,它是可执行程序映像文件的路径kmod,由 Python 脚本在编译时搜索。 (我不会详细介绍大型 Python 脚本系统,因为这远远超出了本答案的范围。)

此方案的缺点是,必须在与安装包的目标机器布局相同且包含相同程序的机器上创建包。每个操作系统的软件包都可能不同(甚至不同版本)。

安装时配置

临时插入

.conf另一种方法是通过生成将服务单元调整为目标系统的插入文件,在安装时配置静态服务单元文件。它们并不理想,因为它们当然会导出到服务进程,但可以使用环境变量来实现此目的。

例如:静态服务单元文件/usr/lib/systemd/system/wibble.service可以说

ExecStart=/usr/bin/wibble $OPTIONS

包维护脚本为了安装然后,action/usr/lib/systemd/system/wibble.service.d/20-options.conf在安装时动态创建一个文件,其中包含安装时在当前计算机上计算的定制选项,而不是在包创建时在不同计算机上计算的定制选项:

环境=选项=摆动 --jelly -o 板

该方案的缺点是包维护脚本卸载如果包被完全清除,操作必须记住删除此文件,并且必须记住将其挂接到配置操作,以便系统管理员在重新配置或重新安排内容时可以显式强制重新生成嵌入式文件。

预处理

上述内容的一个变体是回到宏预处理。实际上传送宏化服务单元文件,并在安装时对其进行预处理。

如果根本不制作软件包,而只是将所有内容放在 ustar 存档中以供系统管理员手动安装,那么这比生成的插件更可行。

这样做的缺点是像 Meson 中的宏预处理系统与 Python 脚本集合紧密耦合,不能作为独立工具使用。对于独立的预处理工具,有以下之类的m4cpp和其他,它们都不适合预处理 .INI 文件并做出各种决策(例如“检测程序wibble在这台机器上采用的选项。”“在这台机器上的位置kmod?”)通常涉及。

显然,这里有一个没人发现的工具的利基市场——至少我听说过。

可以凑合一下command -v 进行路径查找ex在 shell 脚本中进行替换;但是(大多数人不会)针对路径名中的空格和元字符等进行强化,或者允许转义机制来防止不需要的宏扩展,这是很重要的。

Perl 的字符串处理比 shell 脚本更安全,但并不是每个操作系统都具有开箱即用的 Perl(参见“有没有不带 Perl 的类 Unix 系统?”),需要告诉系统管理员确保首先安装 Perl。考虑到 systemd 庞大的 Python 脚本集合构建系统,Python 显然可以做到这一点。但随之而来的问题是系统管理员会去改变你的 Python 版本,然后把地毯从你身下拉出来(参见“重建损坏的 PATH 变量后 apt-get update 不再起作用“以及所有询问 Ubuntu 问题的超链接)。其他可能性包括 TCL。

紧握的手上……

有时这种可配置性本来就是不必要的。systemd@KMOD@中的宏实际上不是必需的。这(现在)可以工作:

ExecStart=kmod static-nodes --format=tmpfiles --output=/run/tmpfiles.d/static-nodes.conf

将数据库表(某种)转变为服务单元?运送发电机。

指定默认启用/禁用状态?运送预设。

答案2

systemd-run用于从命令行启动新的 systemd 服务:

systemd-run [OPTIONS...] {COMMAND} [ARGS...]

看到systemd-run --help并且man systemd-run

它不是持久化的systemd服务,需要编写单元文件。

示例来自RHEL 文档:使用 systemd-run 启动新服务

systemd-run --unit=toptest --slice=test top -b

单元文件将被写入/run/systemd/transient/toptest.service.

相关内容