当文件没有改变时,如何停止 systemd oneshot 运行?

当文件没有改变时,如何停止 systemd oneshot 运行?

我创建了一个 systemd 服务,用于在更新某些 docker 容器的 SSL 证书时重新启动它们。我创建了这个单元文件,这样当服务检测到证书已更改时,就会执行我的脚本来重新启动容器:

[Service]
Type=oneshot
ExecStart=/opt/mailcow-cert-restart/mailcow-cert-restart.sh
Description=Restarts affected mailcow containers when their certificates are renewed by nginx-proxy-manager

[Path]
PathChanged=/opt/compose-stacks/mailcow-dockerized/data/assets/ssl/cert.pem

[Install]
WantedBy=multi-user.target

问题是,当使用以下命令重新启动服务时systemctl restart myservice它会重新启动docker容器,即使证书从那时起没有改变过。有什么方法可以确保脚本将仅有的证书文件更改时会运行吗?我不希望这些容器不必要地重新启动。

答案1

[Path]当然,这种方式行不通。首先,它只在.path单位中起作用——你不能把它放在其他单位类型中。其次,它的机制与你想要的完全相反——它不会阻止任何事情发生,也不会保持持久状态;PathChanged= 的目的是触发事件这会导致服务启动。

您最好在服务的脚本/程序中完成操作 - 每当更新完成时存储一个时间戳(例如“触摸”标记文件);将存储的时间戳与的时间戳进行比较cert.pem

例如,只需几行 bash:

if [[ cert.pem -nt /opt/.mailcow.lastupd ]]; then
    <restart stuff> &&
    touch /opt/.mailcow.lastupd
fi

这也可以作为一个完成ConditionExec(我本来想写的/bin/sh -c "[ ... ]",但[akatest确实作为一个独立程序存在):

[Unit]
ConditionExec=/bin/[ /opt/foo/cert.pem -nt /etc/dovecot/cert.pem ]

相关内容