在 network.service 之前在第一次启动时设置主机名

tho*_*nic 7 dhcp debian hostname systemd

我有一个 firstboot.service,它根据主以太网适配器的 MAC 从库存操作系统映像创建一个唯一的主机名。它在引导期间按预期运行,但使用 DHCP 注册的主机名仍然是内核设置的默认主机名。因此,在设备启动后,我可以 ping 它,defaultname.mynet.lan但是当我登录并调用hostname它时,它会foo-XXXX按预期显示。

如下所示,该服务已注册为在network.target. 正如您可能猜到的那样,我正在使用systemd-networkdsystemd-resolved用于网络。

  • 我是否必须做其他事情才能将主机名传播到正在运行的进程?
  • 我可以在引导过程中更早地设置主机名吗?如果可以,我应该使用什么目标?

首次启动服务

[Unit]
ConditionPathExists=|!/etc/hostname
Before=network.target
After=local-fs.target
After=sys-subsystem-net-devices-eth0.device

[Service]
Type=oneshot
ExecStart=/bin/bash -c "/usr/local/sbin/firstboot.sh"
RemainAfterExit=yes

[Install]
WantedBy=network.target
Run Code Online (Sandbox Code Playgroud)

首次启动文件

HOST_PREFIX=${HOST_PREFIX:-"foo"}
NET_DEVICE=${NET_DEVICE:="eth0"}
LAST_MAC4=$(sed -rn "s/^.*([0-9A-F:]{5})$/\1/gi;s/://p" /sys/class/net/${NET_DEVICE}/address)
NEW_HOSTNAME=${HOST_PREFIX}-${LAST_MAC4:-0000}

echo $NEW_HOSTNAME > /etc/hostname
/bin/hostname -F /etc/hostname
Run Code Online (Sandbox Code Playgroud)

Fer*_*ner 7

没有什么可以确保您firstboot.servicesystemd-networkd开始之前运行。你必须使用

Wants=network-pre.target
Before=network-pre.target
Run Code Online (Sandbox Code Playgroud)

而不是Before=network.target实现这一目标。正如man systemd.special解释:

network-pre.target: 这个被动目标单元可能会被想要在设置任何网络之前运行的服务拉入,例如为了设置防火墙。所有网络管理软件都在此目标之后自行订购,但不会将其拉入。

您还需要DefaultDependencies=false避免对basic.target(参见 参考资料man systemd.service)的隐式依赖。