如何打包一个systemd服务?

我正在尝试将一个Mono应用程序打包成systemd服务来运行。
我按照这里的说明进行操作: https://wiki.debian.org/Teams/pkg-systemd/Packaging 我在我的Debian控制文件的构建依赖中添加了dh-systemd(>= 1.5)。
我在我的规则文件中添加了--with=systemd,如下所示:
%:
    dh $@ --with=cli --with=systemd

我已将我的服务文件添加到名为mypackage.service的debian文件夹中,其内容如下:
[Unit]
Description=My Service Description
After=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/mono /usr/lib/mypackage/myservice.exe

[Install]
WantedBy=multi-user.target

然而,构建过程中出现了以下lintian警告和错误:
Now running lintian...
E: mypackage: postrm-does-not-call-updaterc.d-for-init.d-script     etc/init.d/mypackage
W: mypackage: init.d-script-not-marked-as-conffile etc/init.d/mypackage
E: mypackage: init.d-script-not-included-in-package etc/init.d/mypackage

这个问题让我感到困惑的原因有几个:
1. 这些警告是关于 init.d 的,而 init.d 是旧的系统,已经被 systemd 取代了。这些错误和警告是不是错了?debuild 是不是认为我配置了包时使用了 init.d?
2. 我原本以为使用 --with=systemd 会为我创建这些脚本。 更新 生成的 postrm 文件如下:
#!/bin/sh
set -e
# Automatically added by dh_systemd_start
if [ -d /run/systemd/system ]; then
    systemctl --system daemon-reload >/dev/null || true
fi
# End automatically added section
# Automatically added by dh_systemd_enable
if [ "$1" = "remove" ]; then
    if [ -x "/usr/bin/deb-systemd-helper" ]; then
        deb-systemd-helper mask mypackage.service >/dev/null
    fi
fi

if [ "$1" = "purge" ]; then
     if [ -x "/usr/bin/deb-systemd-helper" ]; then
        deb-systemd-helper purge mypackage.service >/dev/null
        deb-systemd-helper unmask mypackage.service >/dev/null
    fi
fi
# End automatically added section

生成的prerm文件如下所示:
#!/bin/sh
set -e
# Automatically added by dh_systemd_start
if [ -d /run/systemd/system ]; then
    deb-systemd-invoke stop mypackage.service >/dev/null
fi
# End automatically added section
# Automatically added by dh_installinit
if [ -x "/etc/init.d/mypackage" ] || [ -e "/etc/init/mypackage.conf" ]; then
    invoke-rc.d mypackage stop || exit $?
fi
# End automatically added section

包实际上安装得很好,服务也能正确启动。Lintian的错误让人担忧,我希望能找出问题的根源。

你的 postrm 脚本包含什么?它是否有 debhelper 的样板文件? - muru
它在哪里?它是什么?说明书上没有说要创建一个,链接的示例也没有一个。所以要么是由dh-systemd自动生成的,要么根本不存在。 - trampster
2请查看 https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html 和 https://wiki.debian.org/MaintainerScripts。如果您不知道这些是什么,请使用 debhelper(又名 dh)生成适当的脚本。在生成的 deb 文件上运行 dpkg-deb --control,并查看新创建的 DEBIAN 目录中的 postinstpostrm 文件。 - muru
好的,我会按照指示进行操作。指令中提到:“重新构建后,您的软件包将在postinst、prerm和postrm维护脚本中添加额外的代码。”鉴于这些脚本是自动生成的,我很难出错。 - trampster
更新了带有postrm和prerm生成的脚本的问题。 - trampster
2个回答

我也遇到了这个问题。这是我想出来的解决方法:
你需要重写dh_installinit和dh_systemd_start,以下是我网络桥接服务的示例:
#!/usr/bin/make -f

PKGDIR=debian/tmp

%:
    dh $@ --with systemd

override_dh_installinit:
    dh_systemd_enable -popenstack --name=openstack openstack.service
    dh_installinit -popenstack --no-start --noscripts
    dh_systemd_start -popenstack --no-restart-on-upgrade

override_dh_systemd_start:
    echo "Not running dh_systemd_start"

我的软件包的完整源代码可以在这里找到:https://github.com/Ubuntu-Solutions-Engineering/openstack-deb/tree/master/debian 我还参考了https://github.com/lxc/lxd-pkg-ubuntu/blob/dpm-xenial/debian/rules
希望这能帮助你,因为我花了一些时间才弄明白这个。

当不包括SysV或Upstart init脚本时,请指示dh_installinit不要修改postinst/postrm/prerm脚本。由dh_systemd处理。
override_dh_installinit:
    dh_installinit --noscripts

这适用于debhelper兼容性级别<10,并且对于10,即使dh_systemd已合并到debhelper中。

根据https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=800043debhelper兼容性级别11 > = 将修复此问题。