Set hostname on first boot before network.service

5,454

Nothing ensures that your firstboot.service runs before systemd-networkd is started. You have to use

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

instead of Before=network.target to achieve that. As man systemd.special explains:

network-pre.target: This passive target unit may be pulled in by services that want to run before any network is set up, for example for the purpose of setting up a firewall. All network management software orders itself after this target, but does not pull it in.

You'll also need DefaultDependencies=false to avoid the implicit dependency on basic.target (see man systemd.service).

Share:
5,454

Related videos on Youtube

thom_nic
Author by

thom_nic

Generalista

Updated on September 18, 2022

Comments

  • thom_nic
    thom_nic over 1 year

    I have a firstboot.service that, from a stock OS image creates a unique hostname based on the MAC of the primary ethernet adapter. It runs as expected during boot but the hostname that gets registered with DHCP is still the default hostname as set from the kernel. So after the device boots, I can ping it at defaultname.mynet.lan but when I login and call hostname it displays foo-XXXX as expected.

    As you can see below, the service is registered to run before network.target. As you may guess I'm using systemd-networkd and systemd-resolved for networking.

    • Do I have to do something else to propagate the hostname to running processes?
    • Can I set the hostname earlier in the boot process, if so what target should I use?

    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
    
    • Admin
      Admin over 5 years
      If you are trying to change the hostname from the default hostname you can do that in systemd by checking with ConditionHost=ubuntu*
  • Chang Yu-heng
    Chang Yu-heng over 5 years
    Why do we need wants here? Isn't before enough for the requirement?
  • Ferenc Wágner
    Ferenc Wágner over 5 years
    The Wants directive "pulls in" the network-pre.target. Otherwise it may not be present at all, making the ordering ineffective.