openSUSE:Systemd 打包指南

跳转至: 导航, 搜索


本文是 systemd 服务的打包指南。完整范例请见 home:MargueriteSu dnscrypt。

RPM 宏

自 openSUSE 12.1 起,打包 systemd service 文件必须用到几个 RPM 宏。

编译环境

您应该添加:

%if 0%{?suse_version} >= 1210
BuildRequires: systemd
%endif

作为编译依赖。

依赖

添加:

%{?systemd_requires}

来确保您的软件包安装了必要的依赖。

service 文件

服务文件必须被安装到 %{_unitdir} (也就是 /usr/lib/systemd/system) 永远不能安装到 /etc/systemd/system(这样用户就可以覆盖它们了,也和打包不冲突。又叫「mask」)。

在安装脚本中注册 service

添加如下宏到您的脚本:

如果 foo.service bar.service 是您想要安装的两个 systemd 服务:

%pre
%service_add_pre foo.service bar.service

%post
%service_add_post foo.service bar.service

%preun
%service_del_preun foo.service bar.service

%postun
%service_del_postun foo.service bar.service

如果您的软件包也提供了 sysv 启动脚本,这些宏将会透明地处理 sysv 启动脚本迁移 (只要启动脚本和 systemd 服务的名称相同)

如果您的软件包想要支持针对比 12.1 旧的 openSUSE 编译,您应该针对这些宏使用条件测试:

%if %{?suse_version} >= 1210
[...]
%endifIf 

启用服务

默认,服务不会在软件包安装后启用。如果您想要默认启用您的服务,您应该在 OBS 上针对 systemd-presets-branding-openSUSE 软件包做提交,修改 default-openSUSE.preset 文件,添加:

enable your_service_name.service

在 /var/run 和 /run 创建文件/子目录

自 openSUSE 12.2 起,/var/run (通常是绑定到或 symlink 到 /run 的)被作为缓存文件系统挂载。因此软件包不应该再包含在 /var/run(或 /run) 下的任何文件夹/文件了,因为它们会在下次启动后消失。

如果需要在里面创建一个新文件/子目录,您应该打包一个 tmpfiles.d 文件(语法参考 man tmpfiles.d),安装到 /usr/lib/tmpfiles.d/。tmpfiles.d 文件的一个小例子:

# 创建一个权限 0770 所有者 foo 和群组 bar 的目录
d /var/run/my_new_directory 0770 foo bar

您应该在 %install 章节这么安装它们:

%{__install} -d -m 0755 %{buildroot}/usr/lib/tmpfiles.d/
%{__install} -m 0644 %{SOURCE4} %{buildroot}/usr/lib/tmpfiles.d/%{name}.conf

如果您期望文件/目录在软件包安装后立即可用(重启前),添加此行到您的软件包 %post:

systemd-tmpfiles --create /usr/lib/tmpfiles.d/<file_name>

如果不想用 /usr/lib/tmpfiles.d,对于13.1或之后的版本也可以用 %_tmpfilesdir 宏。对于老版本,必须在 spec 文件顶部添加以下内容:

%{!?_tmpfilesdir:%global _tmpfilesdir /usr/lib/tmpfiles.d}

向后兼容性

rc 软链接

/usr/sbin/rcname 软链接仍然可以保留。要让它在 systemd 下工作,将每个单元(支持的服务和目标类型)都链到 /usr/sbin/service :

ln -s /usr/sbin/service %{buildroot}%{_sbindir}/rcname

附加行为

初始化脚本有些情况下会实现除了常规的 start/stop/status 等以外的附加行为。对于 systemd 的 service 文件,这些附加的功能是不存在的。而他们对一些服务仍然很有用。因此 /usr/sbin/service 实现了 "legacy actions",就像 Fedora 中一样。

假设先前的初始化脚本 "foo" 包含一个行为 "frob"。现在 service 文件被命名为 "foo.service" 而你想让它仍然支持 "frob" 行为。那么在工厂版中自 2014-03-11 (13.1之后) 的版本起,你可以创建一个脚本

 /usr/lib/initscripts/legacy-actions/foo/frob

来实现所需要的功能。 显然,此行为只会在 /usr/sbin/service 调用服务的时候启动,例如

 # service foo frob

或者

 # rcfoo frob