web-dev-qa-db-ja.com

network.serviceの前の最初の起動時にホスト名を設定します

私は、最初のイーサネットアダプターのMACに基づいて、ストックOSイメージから一意のホスト名を作成するfirstboot.serviceを持っています。ブート時に期待どおりに実行されますが、DHCPに登録されたホスト名は、カーネルから設定されたデフォルトのホスト名のままです。したがって、デバイスの起動後、defaultname.mynet.lanでpingを実行できますが、ログインしてhostnameを呼び出すと、期待どおりfoo-XXXXが表示されます。

以下に示すように、サービスはnetwork.targetより前に実行するように登録されています。ご想像のとおり、ネットワーキングにはsystemd-networkdsystemd-resolvedを使用しています。

  • 実行中のプロセスにホスト名を伝達するために何か他のことをする必要がありますか?
  • ブートプロセスの早い段階でホスト名を設定できますか?その場合、どのターゲットを使用する必要がありますか?

firstboot.service

[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

firstboot.sh

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
6
thom_nic

firstboot.serviceが起動する前にsystemd-networkdが実行されることを保証するものはありません。あなたが使用する必要があります

Wants=network-pre.target
Before=network-pre.target

それを達成するためにBefore=network.targetの代わりに。 man systemd.specialの説明:

network-pre.target:このパッシブターゲットユニットは、ファイアウォールを設定するなどの目的で、ネットワークを設定する前に実行したいサービスによって引き込まれる場合があります。すべてのネットワーク管理ソフトウェアは、このターゲットの後に自分自身を注文しますが、引き込みません。

DefaultDependencies=falseへの暗黙の依存を回避するために、basic.targetも必要です(man systemd.serviceを参照)。

5
Ferenc Wágner